hihocoder1398 网络流五·最大权闭合子图

思路:

最大权闭合子图。

实现:

  1 #include <bits/stdc++.h>
  2 
  3 #define N (405)
  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 n, m, x, y;
107     while (cin >> n >> m)
108     {
109         dinic_init();
110         int sum = 0;
111         for (int i = 1; i <= m; i++)
112         {
113             cin >> x;
114             add_edge(n + i, n + m + 1, x, 0);
115         }
116         for (int i = 1; i <= n; i++)
117         {
118             cin >> x; sum += x;
119             add_edge(0, i, x, 0);
120             cin >> y;
121             while (y--)
122             {
123                 cin >> x;
124                 add_edge(i, n + x, INF, 0);
125             }
126         }
127         int ans = dinic(0, n + m + 1);
128         cout << sum - ans << endl;
129     }
130     return 0;
131 }
原文地址:https://www.cnblogs.com/wangyiming/p/9893578.html