飞行员配对(二分图最大匹配) 51Nod
飞行员配对(二分图最大匹配)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define CLR(m, a) memset(m, a, sizeof(m)) 4 5 const int maxn = 110; 6 7 int p[maxn][maxn]; 8 int vb[maxn], mcb[maxn]; 9 int n,m; 10 int Hungary(int u){ 11 for(int i = m+1; i <= n; i++) if(p[u][i]&&!vb[i]){ 12 vb[i] = 1; 13 if(mcb[i]==-1 || Hungary(mcb[i])) { 14 mcb[i] = u; 15 return 1; 16 } 17 } 18 return 0; 19 } 20 21 int main(){ 22 scanf("%d %d", &m, &n); 23 int u, v; 24 while(scanf("%d %d", &u, &v)){ 25 if(u==-1 && v==-1) break; 26 p[u][v] = 1; 27 } 28 CLR(mcb, -1); 29 int ans = 0; 30 for(int i = 1; i <= m; i++){ 31 CLR(vb, 0); 32 if(Hungary(i)) ans++; 33 } 34 printf("%d ", ans); 35 }
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxv = 110; 4 const int maxe = 110*110; 5 const int inf = 0x3f3f3f3f; 6 struct Edge{ 7 int u, v, nex; 8 int cap, flow; 9 Edge(int u=0, int v=0, int nex=0, int cap=0, int flow=0): 10 u(u), v(v), nex(nex), cap(cap), flow(flow){} 11 }e[maxe<<1]; 12 int head[maxv]; 13 int cnt; 14 void init(){ 15 memset(head, -1, sizeof(head)); 16 cnt = 0; 17 } 18 19 void add(int u, int v, int cap){ 20 e[cnt] = Edge(u, v, head[u], cap, 0); 21 head[u] = cnt++; 22 e[cnt] = Edge(v, u, head[v], 0, 0); 23 head[v] = cnt++; 24 } 25 26 int d[maxv], num[maxv], cur[maxv], p[maxv]; 27 int vis[maxv]; 28 int S, T; 29 int N; 30 31 void bfs(){ 32 memset(d, -1, sizeof(d)); 33 memset(vis, 0, sizeof(vis)); 34 queue<int> q; 35 q.push(T); 36 vis[T] = 1; 37 d[T] = 0; 38 while(!q.empty()){ 39 int u = q.front(); 40 q.pop(); 41 for(int i = head[u]; ~i; i = e[i].nex){ 42 int id = i&(-2); //正边 43 int v = e[id].u; 44 if(!vis[v] && e[id].cap > e[id].flow){ 45 vis[v] = 1; 46 d[v] = d[u] + 1; 47 q.push(v); 48 } 49 } 50 } 51 } 52 53 int augment(){ 54 int u = T; 55 int a = inf; 56 while(u!=S){ 57 int id = p[u]; 58 a = min(a, e[id].cap - e[id].flow); 59 u = e[id].u; 60 } 61 u = T; 62 while(u!=S){ 63 int id = p[u]; 64 e[id].flow += a; 65 e[id^1].flow -= a; 66 u = e[id].u; 67 } 68 return a; 69 } 70 71 int ISAP(){ 72 bfs(); 73 int flow = 0; 74 memset(num, 0, sizeof(num)); 75 for(int i = 0; i < N; i++){ 76 cur [i] = head[i]; 77 if(~d[i]) num[d[i]]++; 78 } 79 int u = S; 80 while(d[S] < N){ 81 if(u == T){ 82 flow += augment(); 83 u = S; 84 } 85 int ok = 0; 86 for(int i = cur[u]; ~i; i = e[i].nex){ 87 int v = e[i].v; 88 if(d[u] == d[v]+1 && e[i].cap > e[i].flow){ 89 p[v] = i; 90 ok = 1; 91 cur[u] = i; 92 u = v; 93 break; 94 } 95 } 96 if(!ok){ 97 int m = N-1; 98 for(int i = head[u]; ~i; i = e[i].nex){ 99 if(e[i].cap > e[i].flow && ~d[e[i].v]) m = min(m, d[e[i].v]); 100 } 101 if(--num[d[u]] == 0) break; 102 num[d[u]=m+1]++; 103 cur[u] = head[u]; 104 if(u != S) u = e[p[u]].u; 105 } 106 } 107 return flow; 108 } 109 110 int main(){ 111 int n, m; 112 init(); 113 scanf("%d %d", &m, &n); 114 int u, v; 115 while(scanf("%d %d", &u, &v)){ 116 if(u==-1 && v==-1) break; 117 add(u,v,1); 118 } 119 S = 0; T = n+1; 120 N = T+1; 121 for(int i = 1; i <= m; i++){ 122 add(S, i, 1); 123 } 124 for(int i = m+1; i <= n; i++){ 125 add(i, T, 1); 126 } 127 int ans = ISAP(); 128 printf("%d ", ans); 129 }