1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
/* problem: HDU2063 * Auther:CaiCai * 第二次用EK跑二分图,没什么好说的,建好图就一定可以做 * 建图就是女生一边,男生一边,再把源点和束点找到,权值分别是1这样就可以把图建完了。 */ #include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const int maxN=505; int m, n; int temp; int r[maxN<<1][maxN<<1], flow[maxN<<1], pre[maxN<<1]; int sum1 = 0; int sum2 = 0; int K, M, N; int tot; int bfs(int st,int en) { queue<int> q; while(!q.empty()) q.pop(); memset(pre, -1, sizeof pre); pre[0] = 0; flow[0]=INF; q.push(0); while(!q.empty()) { int u = q.front(); q.pop(); for (int i = 1; i <= tot;i++) { if(r[u][i]>0&&pre[i]==-1) { pre[i] = u; flow[i] = min(flow[u], r[u][i]); q.push(i); } } } return pre[en] == -1 ? -1 : flow[en]; } int maxflow(int st,int en) { int icr = 0; int ans = 0; while((icr=bfs(st,en))!=-1) { int k = en; while(k!=st) { int last = pre[k]; r[last][k] -= icr; r[k][last] += icr; k = last; } ans += icr; } return ans; } int main() { while (~scanf("%d",&K)) { if(K==0) break; scanf("%d%d",&M,&N); memset(r, 0, sizeof r); tot = M + N+1; for (int i = 1; i <= M;i++) r[0][i] = 1; for (int i = M + 1; i <= M + N;i++) r[i][tot] = 1; for (int i = 0; i < K; i++) { int a, b; scanf("%d", &a); scanf("%d", &b); r[a][b + M] = 1; } int ans = maxflow(0, tot); printf("%dn", ans); } }
|
近期评论