Nanami and the House Protecting Problem

D06發表於2024-07-02
  • 求出最大流後,從源點開始沿殘量網路BFS,標記能夠到達的點。E中所有連線已標記點和未標記點的邊構成最小割
點選檢視程式碼
#include <bits/stdc++.h>
using namespace std;
vector<int>a[6005];
vector<int>c[6005];
vector<int>d[6005];
bool v[6005];
int pr1[6005],pr2[6005];
char w[1005][1005];
int n,m;
int s=0,t;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
void update(int l)
{
	int p=t;
	while(p!=s)
	{
		c[pr1[p]][pr2[p]]-=l;
		c[p][d[pr1[p]][pr2[p]]]+=l;
		p=pr1[p];
	}
}
int dfs1(int n1,int l)
{
	if(n1==t)
	{
		update(l);
		return l;
	}
	else
	{
		for(int i=0;i<a[n1].size();i++)
		{
			if(c[n1][i]!=0&&v[a[n1][i]]==false)
			{
				pr1[a[n1][i]]=n1;
				pr2[a[n1][i]]=i;
				v[a[n1][i]]=true;
				int va=dfs1(a[n1][i],min(l,c[n1][i]));
				if(va!=0)
				{
					return va;
				}
			}
		}
	}
	return 0;
}
void dfs2(int n1)
{
	v[n1]=true;
	for(int i=0;i<a[n1].size();i++)
	{
		if(v[a[n1][i]]==false&&c[n1][i]!=0)
		{
			dfs2(a[n1][i]);
		}
	}
}
void add(int u,int v,int w)
{
	a[u].push_back(v);
	a[v].push_back(u);
	c[u].push_back(w);
	c[v].push_back(0);
	d[u].push_back(a[v].size()-1);
	d[v].push_back(a[u].size()-1);
}
int id(int i,int j,int opt)
{
	return (i-1)*m+j+opt*n*m;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>n>>m;
		t=2*n*m+1;
		for(int i=0;i<=2*n*m+1;i++)
		{
			a[i].clear();
			c[i].clear();
			d[i].clear();
		}
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				cin>>w[i][j];
				if(w[i][j]=='H')
				{
					add(s,id(i,j,0),INT_MAX);
				}
				if(w[i][j]=='.')
				{
					if(i==1||i==n||j==1||j==m)
					{
						add(id(i,j,1),t,INT_MAX);
					}
				}
			}
		}
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				int f;
				cin>>f;
				if(f>0)
				{
					add(id(i,j,0),id(i,j,1),f);
				}
				else
				{
					add(id(i,j,0),id(i,j,1),INT_MAX);
				}
				if(w[i][j]!='#')
				{
					for(int k=0;k<4;k++)
					{
						if(w[i+dx[k]][j+dy[k]]=='.'||w[i+dx[k]][j+dy[k]]=='H')
						{
							add(id(i+dx[k],j+dy[k],1),id(i,j,0),INT_MAX);
						}
					}
				}
			}
		}
		int ans=0,va;
		memset(v,false,sizeof(v));
		v[s]=true;
		while(va=dfs1(s,INT_MAX))
		{
			for(int i=0;i<=2*n*m+1;i++)
			{
				v[i]=false;
			}
			v[s]=true;
			ans+=va;
		}
		memset(v,false,sizeof(v));
		dfs2(s);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				if(v[id(i,j,0)]==true&&v[id(i,j,1)]==false)
				{
					w[i][j]='#';
				}
			}
		}
		cout<<ans<<endl;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				cout<<w[i][j];
				w[i][j]=' ';
			}
			cout<<endl;
		}
	}
	return 0;
}
/*
1
5 5
1 2 2
2 3 2
3 5 3
1 4 5
4 3 6
*/

相關文章