题意就是任意两个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;
}
呵呵,很有意思吧。