zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    记:vue-router报错: Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location
    使用vuepress搭建GitHub pages静态博客页面
    APPCNA 手势验证登录
    appcan 文件下载与预览
    上传文件-layui+ashx
    2020已经过去五分之四了,你确定还不来了解一下JS的rAF?
    《Python 测试开发技术栈—巴哥职场进化记》—每日站会的意义
    Netty 增加接收缓冲区大小
    我想把Jhipster介绍给你
    如何写好转正答辩PPT
  • 原文地址:https://www.cnblogs.com/kirai/p/6246601.html
Copyright © 2011-2022 走看看