zoukankan      html  css  js  c++  java
  • ZOJ 2532 Internship 网络流求关键边

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2532

    题意:给出一张图,有N个城市,M个中继站,和L条线路连接。

    城市发送数据,最终发送到总部(标号为0),问增大哪些线路带宽能够增加总部接收到的带宽。(考虑一条边的时候,增大这条边,别的不能变化)。

    思路:

    由于时间复杂度,依次把每条边的容量+1,然后求最大流与原来的最大流相比较,这种做法是不可行的。

    考虑最大流算法,是不停地找增广路。

    那么如果一条边u->v,如果从源点开始不停找增广路,能够找到点u。

    从汇点开始反向找增广路,能够找到点v,且u->v满流,那么只要增加这条边的容量,就可以增加最大流,符合题目中的条件。

    由于有多个城市,先设立一个超级源点s,连边到每个城市,容量为正无穷。

    然后把原图中给出的边在图中连接起来,容量即给出的对应值。

    把0号设为汇点。然后求最大流。

    再分别就源点和汇点dfs找出源点增广路能够到达的点from[u] = 1,和汇点增广路能够到达的点to[v] = 1。注意反向找边的时候,判断满流的条件是判断其对应的正向边是否满流。

    检查残量网络中的边,设为u->v,如果这条边满流,且from[u]=1,to[v]=1,则这条边满足条件。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define maxn 110
      4 const int inf = 0x3f3f3f3f;
      5 int N, M, L;
      6 struct Edge
      7 {
      8     int from, to, cap, flow, id;
      9     Edge(int f, int t, int c, int fl, int i)
     10     {
     11         from = f; to = t; cap = c; flow = fl; id = i; 
     12     }
     13 };
     14 int from[maxn], to[maxn];
     15 int n, m, s, t;
     16 vector <Edge> edges;
     17 vector <int> G[maxn];
     18 int vis[maxn], cur[maxn], d[maxn];
     19 void AddEdge(int from, int to, int cap, int id)
     20 {
     21     edges.push_back(Edge(from, to, cap, 0, id));
     22     edges.push_back(Edge(to, from, 0, 0, -1));
     23     m = edges.size();
     24     G[from].push_back(m-2);
     25     G[to].push_back(m-1);
     26 }
     27 bool bfs()
     28 {
     29     memset(vis, 0, sizeof(vis));
     30     vis[s] = 1;
     31     d[s] = 0;
     32     queue <int> q;
     33     q.push(s);
     34     while(!q.empty())
     35     {
     36         int u = q.front(); 
     37         q.pop();
     38         for(int i = 0; i < G[u].size(); i++)
     39         {
     40             Edge &e = edges[G[u][i]];
     41             if(!vis[e.to] && e.cap > e.flow)
     42             {
     43                 vis[e.to] = 1;
     44                 d[e.to] = d[u] + 1;
     45                 q.push(e.to);
     46             }
     47         }
     48     }
     49     return vis[t];
     50 }
     51 int dfs(int x, int a)
     52 {
     53     if(x == t || a == 0) return a;
     54     int flow = 0, f;
     55     for(int &i = cur[x]; i < G[x].size(); i++)
     56     {
     57         Edge &e = edges[G[x][i]];
     58         if(d[x]+1 == d[e.to] && (f = dfs(e.to, min(e.cap-e.flow, a))) > 0)
     59         {
     60             e.flow += f;
     61             edges[G[x][i]^1].flow -= f;
     62             flow += f;
     63             a -= f;
     64             if(a == 0) break;
     65         }
     66     }
     67     return flow;
     68 }
     69 int MaxFlow()
     70 {
     71     int flow = 0;
     72     while(bfs())
     73     {
     74         memset(cur, 0, sizeof(cur));
     75         flow += dfs(s, inf);
     76     }
     77     return flow;
     78 }
     79 void dfsfrom(int fa)
     80 {
     81     from[fa] = 1;
     82     for(int i = 0; i < G[fa].size(); i++)
     83     {
     84         Edge &e = edges[G[fa][i]];
     85         if(e.id == -1) continue;         //反向边
     86         if(from[e.to]) continue;          //已经访问过
     87         if(e.cap == e.flow) continue;   //满流
     88         dfsfrom(e.to);
     89     }
     90 }
     91 void dfsto(int fa)
     92 {
     93     to[fa] = 1;
     94     for(int i = 0; i < G[fa].size(); i++)
     95     {
     96         Edge &e = edges[G[fa][i]];
     97         if(e.id != -1) continue;       //反向边
     98         if(edges[G[fa][i]-1].cap == edges[G[fa][i]-1].flow) continue;  //满流
     99         if(to[e.to]) continue;       //已经访问过
    100         dfsto(e.to);
    101     }
    102 }
    103 int main()
    104 {
    105     while(scanf("%d%d%d", &N,&M,&L) && N)
    106     {
    107         t = 0; s = N+M+1;
    108         edges.clear();
    109         for(int i = 0; i <= N+M+1; i++) G[i].clear();
    110 
    111         for(int i = 1; i <= L; i++)
    112         {
    113             int a, b, c;
    114             scanf("%d%d%d", &a, &b, &c);
    115             AddEdge(a, b, c, i);
    116         }
    117         for(int i = 1; i <= N; i++) AddEdge(s, i, inf, -2);
    118 
    119         int flow = MaxFlow();
    120         memset(from, 0, sizeof(from));
    121         memset(to, 0, sizeof(to));
    122         dfsfrom(s);
    123         dfsto(t);
    124         
    125         bool flag = true;
    126         for(int i = 0; i < 2*L; i += 2)
    127         {
    128             if(edges[i].cap == edges[i].flow 
    129             && from[edges[i].from] && to[edges[i].to])
    130             {
    131                 if(flag){flag = false; printf("%d", edges[i].id);}
    132                 else printf(" %d", edges[i].id);
    133             }
    134         }
    135         printf("
    ");
    136 
    137     }
    138     return 0;
    139 }
  • 相关阅读:
    HDU 4611 Balls Rearrangement 数学
    Educational Codeforces Round 11 D. Number of Parallelograms 暴力
    Knockout.Js官网学习(简介)
    Entity Framework 关系约束配置
    Entity Framework Fluent API
    Entity Framework DataAnnotations
    Entity Framework 系统约定配置
    Entity Framework 自动生成CodeFirst代码
    Entity Framework CodeFirst数据迁移
    Entity Framework CodeFirst尝试
  • 原文地址:https://www.cnblogs.com/titicia/p/4857058.html
Copyright © 2011-2022 走看看