首页 > 代码库 > [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]网络流三·二分图多重匹配