[洛谷2756]飞行员配对方案问题
思路:
设置超级源点、超级汇点,用最大流算法跑二分图最大匹配。
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<queue> 5 const int E=10001,V=202,inf=0x7fffffff; 6 struct Edge { 7 int from,to; 8 bool remain; 9 }; 10 Edge e[(E+V)<<1]; 11 std::vector<int> g[V]; 12 int sz=0; 13 inline void add_edge(const int u,const int v,const bool w) { 14 e[sz]=(Edge){u,v,w}; 15 g[u].push_back(sz); 16 sz++; 17 } 18 int s,t,p[V]; 19 bool a[V]; 20 inline bool Augment() { 21 memset(a,0,sizeof a); 22 std::queue<int> q; 23 q.push(s); 24 a[s]=true; 25 while(!q.empty()&&!a[t]) { 26 int x=q.front(); 27 q.pop(); 28 for(unsigned i=0;i<g[x].size();i++) { 29 Edge &y=e[g[x][i]]; 30 if(!a[y.to]&&y.remain) { 31 p[y.to]=g[x][i]; 32 a[y.to]=a[x]&&y.remain; 33 q.push(y.to); 34 } 35 } 36 } 37 return a[t]; 38 } 39 int f[V]={0}; 40 inline int EdmondsKarp() { 41 int maxflow=0; 42 while(Augment()) { 43 for(int i=t,last,cnt=0;i!=s;i=e[p[i]].from) { 44 e[p[i]].remain^=true; 45 e[p[i]^1].remain^=true; 46 if(i!=s&&i!=t) { 47 if(!(++cnt&1)) { 48 f[i]=last; 49 } 50 else { 51 last=i; 52 } 53 } 54 } 55 maxflow++; 56 } 57 return maxflow; 58 } 59 int main() { 60 int m,n; 61 scanf("%d%d",&m,&n); 62 s=0,t=m+n+1; 63 for(int i=1;i<=m;i++) { 64 add_edge(s,i,true); 65 add_edge(i,s,false); 66 } 67 for(int i=m+1;i<t;i++) { 68 add_edge(i,t,true); 69 add_edge(t,i,false); 70 } 71 for(;;) { 72 int i,j; 73 scanf("%d%d",&i,&j); 74 if((i==-1)&&(j==-1)) break; 75 add_edge(i,j,true); 76 add_edge(j,i,false); 77 } 78 printf("%d\n",EdmondsKarp()); 79 for(int i=1;i<=m;i++) { 80 if(f[i]) printf("%d %d\n",i,f[i]); 81 } 82 return 0; 83 }