zoukankan      html  css  js  c++  java
  • hihocoder1394 网络流四·最小路径覆盖

    思路:

    拆点后进行最大二分匹配。点数 - 最大匹配数即是答案。

    实现:

      1 #include <bits/stdc++.h>
      2 
      3 #define N (1005)
      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         for (int i = 1; i <= m; i++)
    111         {
    112             cin >> x >> y;
    113             add_edge(x, n + y, 1, 0);
    114         }
    115         for (int i = 1; i <= n; i++)
    116             add_edge(0, i, 1, 0);
    117         for (int i = 1; i <= n; i++)
    118             add_edge(i + n, 2 * n + 1, 1, 0);
    119         cout << n - dinic(0, 2 * n + 1) << endl;
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    PHPCMS V9 导航栏当前栏目高亮
    phpcms v9栏目列表调用每一篇文章内容方法
    PHPCMS V9 为今天或几天前文章加new
    vue.js路由参数简单实例讲解------简单易懂
    vue组件知识总结
    vue.js 利用组件之间通讯,写一个弹出框例子
    vue.js组件之间通讯--父组件调用子组件的一些方法,子组件暴露一些方法,让父组件调用
    vue.js组件之间的通讯-----父亲向儿子传递数据,儿子接收父亲的数据
    vue.js通讯----父亲拿儿子的数据
    git常见操作---由简入深
  • 原文地址:https://www.cnblogs.com/wangyiming/p/9893620.html
Copyright © 2011-2022 走看看