最大流模版题,注意都是将点转换成边。再跑模版即可。
#include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<queue> using namespace std; const int maxn=1010,inf=9999999; struct node{ int to,w,rev; }; int iter[maxn],level[maxn]; vector<node>map[maxn]; void add_edge(int s,int t,int w){ map[s].push_back((node){t,w,map[t].size()}); map[t].push_back((node){s,0,map[s].size()-1}); } void bfs(int s){ memset(level,-1,sizeof(level)); queue<int>q; level[s]=0; q.push(s); while(!q.empty()){ int v=q.front(); q.pop(); for(int i=0;i<map[v].size();++i){ if(level[map[v][i].to]<0&&map[v][i].w>0){ level[map[v][i].to]=level[v]+1; q.push(map[v][i].to); } } } } int dfs(int s,int t,int k){ if(s==t){ return k; } for(int &i=iter[s];i<map[s].size();++i){ node &edge=map[s][i]; if(edge.w>0&&level[edge.to]>level[s]){ int d=dfs(edge.to,t,min(k,edge.w)); if(d>0){ edge.w-=d; map[edge.to][edge.rev].w+=d; return d; } } } return -1; } int max_flow(int s,int t){ int ret=0; for(;;){ bfs(s); if(level[t]<0)break; memset(iter,0,sizeof(iter)); while(1){ int d=dfs(s,t,inf); if(d<=0)break; ret+=d; } } return ret; } int main(){ int s,t; int n,p,q; cin>>n>>p>>q; s=2*n+2*p+2*q+1; t=2*n+2*p+2*q+2; for(int i=2;i<=2*n+2*p+2*q;i+=2){ add_edge(i,i-1,1); if(i-1>2*n&&i-1<2*n+2*p){ add_edge(i-1,t,1); } if(i>2*n+2*p){ add_edge(s,i,1); } } for(int i=1;i<=n;++i){ for(int j=1;j<=p;++j){ bool b; cin>>b; if(b) add_edge(i*2-1,2*j+2*n,1); } } for(int i=1;i<=n;++i){ for(int j=1;j<=q;++j){ bool b; cin>>b; if(b) add_edge(2*p+2*n+j*2-1,i*2,1); } } cout<<max_flow(s,t); return 0; }
时间: 2024-10-14 07:29:19