zoukankan      html  css  js  c++  java
  • hihocoder1393 网络流三·二分图多重匹配

    思路:
    构图后使用dinic算法,如果最大流等于sum(m[i])(i = 1, 2, 3, ..., M),则可以,否则不行。

    实现:

      1 #include <bits/stdc++.h>
      2 
      3 #define N (205)
      4 #define M (N * N + 4 * N)
      5 const int INF = 0x3f3f3f3f;
      6 typedef long long LL;
      7 
      8 using namespace std;
      9 
     10 struct edge 
     11 {
     12     int v, cap, next;
     13 };
     14 edge e[M];
     15 
     16 int head[N], level[N], cur[N];
     17 int num_of_edges;
     18 
     19 void dinic_init(void) 
     20 {
     21     num_of_edges = 0;
     22     memset(head, -1, sizeof(head));
     23     return;
     24 }
     25 
     26 int add_edge(int u, int v, int c1, int c2) 
     27 {
     28     int& i = num_of_edges;
     29 
     30     assert(c1 >= 0 && c2 >= 0 && c1 + c2 >= 0); // check for possibility of overflow
     31     e[i].v = v;
     32     e[i].cap = c1;
     33     e[i].next = head[u];
     34     head[u] = i++;
     35 
     36     e[i].v = u;
     37     e[i].cap = c2;
     38     e[i].next = head[v];
     39     head[v] = i++;
     40     return i;
     41 }
     42 
     43 int dfs(int u, int t, int bn) 
     44 {
     45     if (u == t) return bn;
     46     int left = bn;
     47     for (int &i = cur[u]; i >= 0; i = e[i].next) 
     48     {
     49         int v = e[i].v;
     50         int c = e[i].cap;
     51         if (c > 0 && level[u] + 1 == level[v]) 
     52         {
     53             int flow = dfs(v, t, min(left, c));
     54             if (flow > 0) 
     55             {
     56                 e[i].cap -= flow;
     57                 e[i ^ 1].cap += flow;
     58                 cur[u] = i;
     59                 left -= flow;
     60                 if (!left) break;
     61             }
     62         }
     63     }
     64     if (left > 0) level[u] = 0;
     65     return bn - left;
     66 }
     67 
     68 bool bfs(int s, int t) 
     69 {
     70     memset(level, 0, sizeof(level));
     71     level[s] = 1;
     72     queue<int> q;
     73     q.push(s);
     74     while (!q.empty()) 
     75     {
     76         int u = q.front();
     77         q.pop();
     78         if (u == t) return true;
     79         for (int i = head[u]; i >= 0; i = e[i].next) 
     80         {
     81             int v = e[i].v;
     82             if (!level[v] && e[i].cap > 0) 
     83             {
     84                 level[v] = level[u] + 1;
     85                 q.push(v);
     86             }
     87         }
     88     }
     89     return false;
     90 }
     91 
     92 LL dinic(int s, int t) 
     93 {
     94     LL max_flow = 0;
     95 
     96     while (bfs(s, t)) 
     97     {
     98         memcpy(cur, head, sizeof(head));
     99         max_flow += dfs(s, t, INT_MAX);
    100     }
    101     return max_flow;
    102 }
    103 
    104 int main()
    105 {
    106     int T, n, m;
    107     cin >> T;
    108     while (T--)
    109     {
    110         dinic_init();
    111         int x, y, sum = 0;
    112         cin >> n >> m;
    113         for (int i = 1; i <= m; i++)
    114         {
    115             cin >> x;
    116             sum += x;
    117             add_edge(n + i, n + m + 1, x, 0);
    118         }
    119         for (int i = 1; i <= n; i++)
    120         {
    121             cin >> x;
    122             add_edge(0, i, x, 0);
    123             cin >> y;
    124             while (y--)
    125             {
    126                 cin >> x;
    127                 add_edge(i, n + x, 1, 0);
    128             }
    129         }
    130         if (dinic(0, n + m + 1) == sum) cout << "Yes" << endl;
    131         else cout << "No" << endl;
    132     }
    133     return 0;
    134 }
  • 相关阅读:
    P1012拼数
    P1622释放囚犯
    P1064 金明的预算方案
    P1754球迷购票问题
    卡塔兰数
    P1474货币系统
    P2562kitty猫基因
    P3984高兴的津津
    5-servlet简介
    java通过百度AI开发平台提取身份证图片中的文字信息
  • 原文地址:https://www.cnblogs.com/wangyiming/p/9879432.html
Copyright © 2011-2022 走看看