51nod 2006 飛行員配對【網路流】
阿新 • • 發佈:2018-12-19
設源點s=0,匯點t=n+1。源點到所有外國飛行員建邊,權值為1;所有英國飛行員到匯點建邊,權值為1;能匹配的外國飛行員與英國飛行員建邊,權值為1。那麼問題轉化為求最大流,s到t的最大流就是最大匹配。其實就是一道sb題
二分匹配也能做 無聊的可以敲一發
#include "bits/stdc++.h" using namespace std; const int inf = 0x3f3f3f3f; struct edge { int v,w,nxt; }g[10000]; int s,t; int head[400]; int cur[400]; int cnt; int dis[400]; int n,m; void addedge(int u,int v,int w) { g[cnt].v=v; g[cnt].w=w; g[cnt].nxt=head[u]; head[u]=cnt; ++cnt; } bool bfs() { memset(dis,0,sizeof(dis)); dis[s]=1; queue<int>q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=g[i].nxt) { int v=g[i].v; if(dis[v]==0&&g[i].w>0) { dis[v]=dis[u]+1; if(v==t) return 1; q.push(v); } } } return dis[t]!=0; } int dfs(int u,int flow) { if(u==t)return flow; int ans=0,x=0; for(int &i=cur[u];i!=-1;i=g[i].nxt) { int v=g[i].v; if((dis[v]==dis[u]+1)&&g[i].w>0) { x=dfs(v,min(g[i].w,flow-ans)); g[i].w-=x; g[i^1].w+=x; //if(g[i].w)cur[u]=i; ans+=x; if(ans==flow) return flow; } } if(ans==0) dis[u]=0; return ans; } int main() { scanf("%d%d",&m,&n); s=0; t=n+1; cnt=0; memset(head,-1,sizeof(head)); memset(g,0,sizeof(g)); for(int i=1;i<=m;i++) { addedge(s,i,1); addedge(i,s,0); } for(int i=m+1;i<=n;i++) { addedge(i,t,1); addedge(t,i,0); } int x,y; while(scanf("%d%d",&x,&y)&&(x!=-1&&y!=-1)) { //if(x>y)swap(x,y); addedge(x,y,1); addedge(y,x,0); } int ans=0; while (bfs()) { for(int i=0;i<=n;i++) { cur[i]=head[i]; } ans+=dfs(0,inf); } if(ans==0)puts("No Solution!"); else printf("%d\n",ans); }