首页 > 代码库 > [HIHO1393]网络流三·二分图多重匹配
[HIHO1393]网络流三·二分图多重匹配
题目链接:http://hihocoder.com/problemset/problem/1393
把项目到汇点的边权值都加起来,跑完最大流后看是否最大流=权值和。如果等于权值和说明所有项目都有足够的人参与。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef struct Edge { 5 int u, v, w, next; 6 }Edge; 7 const int inf = 0x7f7f7f7f; 8 const int maxn = 511; 9 const int maxm = 20010; 10 int cnt, dhead[maxn]; 11 int cur[maxn], dd[maxn]; 12 Edge dedge[maxm]; 13 int S, T, N; 14 15 void init() { 16 memset(dhead, -1, sizeof(dhead)); 17 for(int i = 0; i < maxn; i++) dedge[i].next = -1; 18 cnt = 0; 19 } 20 21 void adde(int u, int v, int w, int c1) { 22 dedge[cnt].u = u; dedge[cnt].v = v; dedge[cnt].w = w; 23 dedge[cnt].next = dhead[u]; dhead[u] = cnt++; 24 dedge[cnt].u = v; dedge[cnt].v = u; dedge[cnt].w = c1; 25 dedge[cnt].next = dhead[v]; dhead[v] = cnt++; 26 } 27 28 bool bfs(int s, int t, int n) { 29 queue<int> q; 30 for(int i = 0; i < n; i++) dd[i] = inf; 31 dd[s] = 0; 32 q.push(s); 33 while(!q.empty()) { 34 int u = q.front(); q.pop(); 35 for(int i = dhead[u]; ~i; i = dedge[i].next) { 36 if(dd[dedge[i].v] > dd[u] + 1 && dedge[i].w > 0) { 37 dd[dedge[i].v] = dd[u] + 1; 38 if(dedge[i].v == t) return 1; 39 q.push(dedge[i].v); 40 } 41 } 42 } 43 return 0; 44 } 45 46 int dinic(int s, int t, int n) { 47 int st[maxn], top; 48 int u; 49 int flow = 0; 50 while(bfs(s, t, n)) { 51 for(int i = 0; i < n; i++) cur[i] = dhead[i]; 52 u = s; top = 0; 53 while(cur[s] != -1) { 54 if(u == t) { 55 int tp = inf; 56 for(int i = top - 1; i >= 0; i--) { 57 tp = min(tp, dedge[st[i]].w); 58 } 59 flow += tp; 60 for(int i = top - 1; i >= 0; i--) { 61 dedge[st[i]].w -= tp; 62 dedge[st[i] ^ 1].w += tp; 63 if(dedge[st[i]].w == 0) top = i; 64 } 65 u = dedge[st[top]].u; 66 } 67 else if(cur[u] != -1 && dedge[cur[u]].w > 0 && dd[u] + 1 == dd[dedge[cur[u]].v]) { 68 st[top++] = cur[u]; 69 u = dedge[cur[u]].v; 70 } 71 else { 72 while(u != s && cur[u] == -1) { 73 u = dedge[st[--top]].u; 74 } 75 cur[u] = dedge[cur[u]].next; 76 } 77 } 78 } 79 return flow; 80 } 81 82 int n, m; 83 int a, b, v; 84 85 int main() { 86 // freopen("in", "r", stdin); 87 int Q; 88 scanf("%d", &Q); 89 while(Q--) { 90 scanf("%d%d",&n,&m); 91 S = 0, T = n + m + 1; N = n + m + 2; 92 init(); 93 int ss = 0; 94 for(int i = 1; i <= m; i++) { 95 scanf("%d", &a); 96 ss += a; 97 adde(i+n, T, a, 0); 98 } 99 for(int i = 1; i <= n; i++) { 100 scanf("%d %d", &a, &b); 101 adde(S, i, a, 0); 102 for(int j = 0; j < b; j++) { 103 scanf("%d", &v); 104 adde(i, n+v, 1, 0); 105 } 106 } 107 int ret = dinic(S, T, N); 108 if(ret == ss) puts("Yes"); 109 else puts("No"); 110 } 111 return 0; 112 }
[HIHO1393]网络流三·二分图多重匹配
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。