zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    python中字典dict pop方法
    Markdown 学习资源
    Windows bat 设置代理
    Warning: Permanently added '...' (RSA) to the list of known hosts --Windows下git bash 警告处理
    subilme增加对markdown的高亮支持
    ubuntu笔记1
    Sublime Python 插件配置合集
    Excel VBA 快捷键 代码
    贩卖守望先锋账号
    如何用VS2017用C++语言写Hello world 程序?
  • 原文地址:https://www.cnblogs.com/wangyiming/p/9893578.html
Copyright © 2011-2022 走看看