zoukankan      html  css  js  c++  java
  • poj 3204

    告诉了一个有向图G(V,E)、源点S、汇点T。假设这个网络图的最大流是mflow。那么请问,一共有多少条这样的边:仅仅增加此条边的容量上限,可以使得mflow变大,输出这些边分别是什么。

    先跑一遍最大流得到残留网络。

    从st深搜残留网络中所有未满流的边,把能到达的点标记。

    从en做同样的事。

    显然对于一条满足题意的边必有u在st能到达。v在en能到达。

    枚举所有边即可。

      1 // File Name: 3204.cpp
      2 // Author: Missa
      3 // Created Time: 2013/4/18 星期四 22:48:07
      4 
      5 #include<iostream>
      6 #include<cstdio>
      7 #include<cstring>
      8 #include<algorithm>
      9 #include<cmath>
     10 #include<queue>
     11 #include<stack>
     12 #include<string>
     13 #include<vector>
     14 #include<cstdlib>
     15 #include<map>
     16 #include<set>
     17 using namespace std;
     18 #define CL(x,v) memset(x,v,sizeof(x));
     19 #define R(i,st,en) for(int i=st;i<en;++i)
     20 #define LL long long
     21 
     22 const int inf = 0x3f3f3f3f;
     23 const int maxn = 501;
     24 const int maxm = 5001;
     25 struct Edge
     26 {
     27     int v, c, next;//指向点,流量,下一个点
     28 }p[maxm << 1];
     29 int head[maxn], e;
     30 int d[maxn], cur[maxn];//层次记录,当前弧优化
     31 int n, m, st, en;
     32 inline void init()
     33 {
     34     e = 0;
     35     memset(head, -1, sizeof(head));
     36 }
     37 inline void addEdge(int u, int v, int c)
     38 {
     39     p[e].v = v; p[e].c = c; 
     40     p[e].next = head[u];head[u] = e++;
     41     p[e].v = u; p[e].c = 0; //无向图时逆边赋值流量cap,有向图时赋值0.
     42     p[e].next = head[v];head[v] = e++;
     43 }
     44 inline int bfs(int st, int en)
     45 {
     46     queue <int> q;
     47     memset(d, 0, sizeof(d));
     48     d[st] = 1;
     49     q.push(st);
     50     while (!q.empty())
     51     {
     52         int u = q.front(); q.pop();
     53         for (int i = head[u]; i != -1; i = p[i].next)
     54         {
     55             if (p[i].c > 0 && !d[p[i].v])
     56             {
     57                 d[p[i].v] = d[u] + 1;
     58                 q.push(p[i].v);
     59             }
     60         }
     61     }
     62     return d[en];
     63 }
     64 inline int dfs(int u, int a)//a表示流量
     65 {
     66     if (u == en || a == 0) return a;
     67     int f, flow = 0;
     68     for (int& i = cur[u]; i != -1; i = p[i].next)
     69     {
     70         if (d[u] + 1 == d[p[i].v] && (f = dfs(p[i].v,min(a,p[i].c))) > 0)
     71         {
     72             p[i].c -= f;
     73             p[i^1].c += f;
     74             flow += f;
     75             a -= f;
     76             if (!a) break;
     77         }
     78     }
     79     return flow;
     80 }
     81 inline int dinic(int st, int en)
     82 {
     83     int res = 0;
     84     while (bfs(st, en))
     85     {
     86         for (int i = 0; i <= n; ++i)
     87             cur[i] = head[i];
     88         res += dfs(st, inf);
     89     }
     90     return res;
     91 }
     92 int vis[maxn];
     93 inline void dfs1(int u)
     94 {
     95     vis[u] = 1;//src可达
     96     for (int i = head[u]; i != -1; i = p[i].next)
     97         if (vis[p[i].v] == 0 && p[i].c )
     98             dfs1(p[i].v);
     99 }
    100 inline void dfs2(int u)
    101 {
    102     vis[u] = 2;
    103     for (int i = head[u]; i != -1; i = p[i].next)
    104         if (vis[p[i].v] == 0 && p[i^1].c )
    105             dfs2(p[i].v);
    106 }
    107 int main()
    108 {
    109     while(~scanf("%d%d",&n,&m))
    110     {
    111         init();
    112         st = 1, en = n;
    113         for (int i =1 ; i <= m; ++i)
    114         {
    115             int u , v, c;
    116             scanf("%d%d%d",&u,&v,&c);
    117             addEdge(u + 1, v + 1, c);
    118         }
    119         int ans = dinic(st, en);
    120         memset(vis, 0, sizeof(vis));
    121         dfs1(st);dfs2(en);
    122         ans = 0;
    123         for (int i = 0; i < e; i += 2)//i += 2.
    124             if (vis[p[i].v] == 2 && vis[p[i^1].v] == 1)
    125             ans ++;
    126         printf("%d\n",ans);
    127     }
    128     return 0;
    129 }
  • 相关阅读:
    Silverlight第三方控件收集
    我们三十以后才明白
    修复编译Silverlight&quot;不能找到AppManifest.xaml&rdquo;的错误
    Android消息通知
    理解和认识udev
    QT进度条
    WARNING: Application does not specify an API level requirement!
    Linux设备驱动中的异步通知与异步I/O
    Qtopia2.2.0 的配置和交叉编译
    Android Menus
  • 原文地址:https://www.cnblogs.com/Missa/p/3029781.html
Copyright © 2011-2022 走看看