COGS 14. [网络流24题] 搭配飞行员
14. [网络流24题] 搭配飞行员
建边的时候要先从源点向主飞行员和从副飞行员向汇点连边
输入的时候只在两人之间连边
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 #define maxn 10000 5 #define inf 100000000 6 int n,m,src,dec,cur[maxn],ans,lev[maxn]; 7 int front[maxn],head,tail,que[maxn],tot; 8 9 struct node 10 { 11 int to,next,cap; 12 }e[maxn]; 13 inline void add(int u,int v,int w) 14 { 15 e[++tot].to=v; e[tot].next=front[u]; e[tot].cap=w; front[u]=tot; 16 e[++tot].to=u; e[tot].next=front[v]; e[tot].cap=0; front[v]=tot; 17 } 18 19 bool bfs() 20 { 21 for(int i=src;i<=dec;i++) lev[i]=-1,cur[i]=front[i]; 22 head=tail=0; 23 que[tail++]=src; lev[src]=0; 24 while(head<tail) 25 { 26 for(int i=front[que[head]];i;i=e[i].next) 27 if(e[i].cap>0&&lev[e[i].to]==-1) 28 { 29 lev[e[i].to]=lev[que[head]]+1; 30 que[tail++]=e[i].to; 31 if(e[i].to==dec) return true; 32 } 33 head++; 34 } 35 return false; 36 } 37 int dinic(int u,int flow) 38 { 39 if(u==dec) return flow; 40 int res=0,delta; 41 for(int &i=cur[u];i;i=e[i].next) 42 { 43 if(e[i].cap>0&&lev[e[i].to]>lev[u]) 44 { 45 delta=dinic(e[i].to,min(e[i].cap,flow-res)); 46 if(delta) 47 { 48 e[i].cap-=delta; e[i^1].cap+=delta; 49 res+=delta; if(res==flow) break; 50 } 51 } 52 } 53 if(res!=flow) lev[u]=-1; 54 return res; 55 } 56 57 int main() 58 { 59 freopen("flyer.in","r",stdin); 60 freopen("flyer.out","w",stdout); 61 scanf("%d%d",&n,&m); 62 int u,v,w; 63 src=0; dec=n+1; 64 for(int i=1;i<=m;i++) add(src,i,1); 65 for(int i=m+1;i<=n;i++) add(i,dec,1); 66 while(scanf("%d%d",&u,&v)!=EOF) 67 { 68 add(u,v,1); 69 } 70 while(bfs()) 71 ans+=dinic(src,inf); 72 printf("%d\n",ans); 73 return 0; 74 }