uva 12549 最大流
思路:这题的原型题是比较经典的网络流。原型题模型就是把所有的障碍去掉。
有障碍做法还是一样的,只用将每个列和行重新划分,求最大流就行了。
#include <cstring> #include <algorithm> #include <vector> #include <cstdio> #define Maxn 120010 #define Maxm 210000 #define LL int #define inf 100000000 #define Abs(a) (a)>0?(a):(-a) using namespace std; struct Edge{ int from,to,next; LL val; }edge[Maxm]; const double eps=1e-9; LL value[Maxn]; int head[Maxn],work[Maxn],dis[Maxn],q[Maxn],e,vi[Maxn]; void init() { e=0; memset(head,-1,sizeof(head)); } void add1(int u,int v,LL c)//有向边 { edge[e].to=v;edge[e].val=c;edge[e].next=head[u];head[u]=e++; edge[e].to=u;edge[e].val=0;edge[e].next=head[v];head[v]=e++; } void add2(int u,int v,LL c)//无向边 { edge[e].to=v;edge[e].val=c;edge[e].next=head[u];head[u]=e++; edge[e].to=u;edge[e].val=c;edge[e].next=head[v];head[v]=e++; } int bfs(int S,int T) { int rear=0; memset(dis,-1,sizeof(dis)); dis[S]=0;q[rear++]=S; for(int i=0;i<rear;i++) { for(int j=head[q[i]];j!=-1;j=edge[j].next) { if(edge[j].val&&dis[edge[j].to]==-1) { dis[edge[j].to]=dis[q[i]]+1; q[rear++]=edge[j].to; if(edge[j].to==T) return 1; } } } return 0; } LL dfs(int cur,LL a,int T) { if(cur==T) return a; for(int &i=work[cur];i!=-1;i=edge[i].next) { if(edge[i].val&&dis[edge[i].to]==dis[cur]+1) { LL t=dfs(edge[i].to,min(a,edge[i].val),T); if(t) { edge[i].val-=t; edge[i^1].val+=t; return t; } } } return 0; } LL Dinic(int S,int T) { LL ans=0; while(bfs(S,T)) { memcpy(work,head,sizeof(head)); while(LL t=dfs(S,inf,T)) ans+=t; } return ans; } int g[110][110],row,col,beg[110][110],gg[110][110]; void build(int n,int m) { int i,j,f=0; row=col=0; for(i=1;i<=m;i++){ f=0; for(j=1;j<=n;j++){ if(g[j][i]==2) f=0; if(g[j][i]!=2&&!f) col++,f=1; if(g[j][i]!=2) beg[j][i]=col; } } for(i=1;i<=n;i++){ f=0; for(j=1;j<=m;j++){ if(g[i][j]==2) f=0; if(g[i][j]!=2&&!f) row++,f=1; if(g[i][j]!=2) gg[i][j]=row; } } for(i=1;i<=row;i++){ add1(0,i,1); } for(i=1;i<=col;i++){ add1(i+row,row+col+1,1); } for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(g[i][j]==1){ add1(gg[i][j],beg[i][j]+row,1); } } } } int main() { int n,m,i,j,num=0,t,x,y,p,w; scanf("%d",&t); while(t--){ init(); memset(g,0,sizeof(g)); memset(beg,0,sizeof(beg)); memset(gg,0,sizeof(gg)); scanf("%d%d",&n,&m); scanf("%d",&p); for(i=1;i<=p;i++){ scanf("%d%d",&x,&y); g[x][y]=1; } scanf("%d",&w); for(i=1;i<=w;i++){ scanf("%d%d",&x,&y); g[x][y]=2; } build(n,m); if(row==0||col==0||p==0){ printf("0\n"); continue; } int ans=Dinic(0,row+col+1); printf("%d\n",ans); } return 0; }