[洛谷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 }

 

posted @ 2017-07-28 14:08  skylee03  阅读(126)  评论(0编辑  收藏  举报