ZJOI2009狼和羊的故事--dinic網絡流

題意就是任意兩個1和2都不能有路徑相連通。

做法是最小割,但是暴力增廣會T4個點,而dinic沒記cur數組會T2個點,開了以後速度飛快。。。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=105,Maxn=maxn*maxn,inf=1e9,dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int a[maxn][maxn],dep[Maxn],cur[Maxn];
int Begin[Maxn],Next[Maxn*10],to[Maxn*10],p[Maxn*10],e=1;
void add(int u,int v,int flow){
	to[++e]=v,Next[e]=Begin[u],Begin[u]=e,p[e]=flow;
	to[++e]=u,Next[e]=Begin[v],Begin[v]=e,p[e]=0;
}
queue<int>q;
bool bfs(int s,int t){
	memset(dep,0,sizeof(dep));
	while(!q.empty())q.pop();
	dep[s]=1,q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=Begin[u];i;i=Next[i])
			if((!dep[to[i]])&&(p[i]))
				dep[to[i]]=dep[u]+1,q.push(to[i]);
	}
	return (dep[t]>0);
}
int dfs(int u,int t,int Maxflow){
	if(u==t)return Maxflow;
	int tmp;
	for(int &i=cur[u];i;i=Next[i])
		if((dep[to[i]]==dep[u]+1)&&(p[i]))
			if(tmp=dfs(to[i],t,min(Maxflow,p[i]))){
				p[i]-=tmp,p[i^1]+=tmp;
				return tmp;
			}
	return 0;
}
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			scanf("%d",&a[i][j]);
			if(a[i][j]==1)
				add(0,(i-1)*m+j,inf);
			else if(a[i][j]==2)
				add((i-1)*m+j,n*m+1,inf);
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i][j]!=2)
				for(int k=0;k<4;k++){
					int x=i+dir[k][0],y=j+dir[k][1];
					if((x>0)&&(y>0)&&(x<=n)&&(y<=m)&&(a[x][y]!=1))
						add((i-1)*m+j,(x-1)*m+y,1);	
				}
	int ans=0,res;
	while(bfs(0,n*m+1)){
		for(int i=0;i<=n*m+1;i++)cur[i]=Begin[i];
		while(res=dfs(0,n*m+1,inf))ans+=res;
	}
	printf("%d\n",ans);
	return 0;
}

呵呵,很有意思吧。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章