zoukankan      html  css  js  c++  java
  • POJ-1273-Drainage Ditches(网络流之最大流)

    Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage ditches so that Bessie's clover patch is never covered in water. Instead, the water is drained to a nearby stream. Being an ace engineer, Farmer John has also installed regulators at the beginning of each ditch, so he can control at what rate water flows into that ditch. 
    Farmer John knows not only how many gallons of water each ditch can transport per minute but also the exact layout of the ditches, which feed out of the pond and into each other and stream in a potentially complex network. 
    Given all this information, determine the maximum rate at which water can be transported out of the pond and into the stream. For any given ditch, water flows in only one direction, but there might be a way that water can flow in a circle. 

    Input

    The input includes several cases. For each case, the first line contains two space-separated integers, N (0 <= N <= 200) and M (2 <= M <= 200). N is the number of ditches that Farmer John has dug. M is the number of intersections points for those ditches. Intersection 1 is the pond. Intersection point M is the stream. Each of the following N lines contains three integers, Si, Ei, and Ci. Si and Ei (1 <= Si, Ei <= M) designate the intersections between which this ditch flows. Water will flow through this ditch from Si to Ei. Ci (0 <= Ci <= 10,000,000) is the maximum rate at which water will flow through the ditch.

    Output

    For each case, output a single integer, the maximum rate at which water may emptied from the pond.

    Sample Input

    5 4
    1 2 40
    1 4 20
    2 4 20
    2 3 30
    3 4 10
    

    Sample Output

    50

    题解

    这道题是一道裸的最大流,没什么好说的

    不过这里有一个坑

    每次加边的head数组要初始化为-1,自己以前都是0,被坑了

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<queue>
     6 #define N 205
     7 #define MAX 1e8
     8 using namespace std;
     9 int n,m,x,y,z,tot,ans,fee,Min;
    10 int head[N],level[N];
    11 struct node{
    12     int next,to,fee;
    13 }e[2*N];
    14 void add(int x,int y,int z){
    15     e[tot].next=head[x];
    16     head[x]=tot;
    17     e[tot].to=y;
    18     e[tot].fee=z;
    19     tot++;
    20     e[tot].next=head[y];
    21     head[y]=tot;
    22     e[tot].to=x;
    23     e[tot].fee=0;
    24     tot++;
    25 }
    26 queue<int> q;
    27 bool bfs(int s,int t){
    28     memset(level,0,sizeof(level));
    29     level[s]=1;
    30     while (!q.empty()) q.pop();
    31     q.push(s);
    32     while (!q.empty()){
    33         int k=q.front();
    34         q.pop();
    35         if (k==t) return true;
    36         for (int i=head[k];i!=-1;i=e[i].next){
    37             int v=e[i].to;
    38             if (e[i].fee&&!level[v]){
    39                 level[v]=level[k]+1;
    40                 q.push(v);
    41             }
    42         }
    43     }
    44     return false;
    45 }
    46 int dfs(int s,int maxf,int t){
    47     if (s==t) return maxf;
    48     int ret=0;
    49     for (int i=head[s];i!=-1;i=e[i].next){
    50         int v=e[i].to;
    51         fee=e[i].fee;
    52         if (level[v]==level[s]+1){
    53             Min=min(maxf-ret,fee);
    54             fee=dfs(v,Min,t);
    55             e[i].fee-=fee;
    56             e[i^1].fee+=fee;
    57             ret+=fee;
    58             if (ret==maxf) return ret; 
    59         }
    60     }
    61     return ret;
    62 }
    63 int Dinic(int s,int t){
    64     ans=0;
    65     while (bfs(s,t)) ans+=dfs(s,MAX,t);
    66     return ans;
    67 }
    68 int main(){
    69     while (~scanf("%d%d",&n,&m)){
    70         tot=0;
    71         memset(head,-1,sizeof(head));
    72         for (int i=1;i<=n;i++)
    73             scanf("%d%d%d",&x,&y,&z),add(x,y,z);
    74         printf("%d
    ",Dinic(1,m));
    75     }
    76     return 0;
    77 }
    View Code

     这是之前做的

    现在发现Dinic有一个不错的优化

    就是在dfs找答案的时候判断答案是否为0,为0的话就说明当前这个点到达不了汇点,那么直接把level改为0,这样可以减少很多重复的操作

    因为有可能很多的层次网络都是经过s的,那么把s的level改掉后就有很多不用做了

    其实就多了一句话而已

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<queue>
     6 #define N 205
     7 #define MAX 1e8
     8 using namespace std;
     9 int n,m,x,y,z,tot,ans,fee,Min;
    10 int head[N],level[N];
    11 struct node{
    12     int next,to,fee;
    13 }e[2*N];
    14 void add(int x,int y,int z){
    15     e[tot].next=head[x];
    16     head[x]=tot;
    17     e[tot].to=y;
    18     e[tot].fee=z;
    19     tot++;
    20     e[tot].next=head[y];
    21     head[y]=tot;
    22     e[tot].to=x;
    23     e[tot].fee=0;
    24     tot++;
    25 }
    26 queue<int> q;
    27 bool bfs(int s,int t){
    28     memset(level,0,sizeof(level));
    29     level[s]=1;
    30     while (!q.empty()) q.pop();
    31     q.push(s);
    32     while (!q.empty()){
    33         int k=q.front();
    34         q.pop();
    35         if (k==t) return true;
    36         for (int i=head[k];i!=-1;i=e[i].next){
    37             int v=e[i].to;
    38             if (e[i].fee&&!level[v]){
    39                 level[v]=level[k]+1;
    40                 q.push(v);
    41             }
    42         }
    43     }
    44     return false;
    45 }
    46 int dfs(int s,int maxf,int t){
    47     if (s==t) return maxf;
    48     int ret=0;
    49     for (int i=head[s];i!=-1;i=e[i].next){
    50         int v=e[i].to;
    51         fee=e[i].fee;
    52         if (level[v]==level[s]+1){
    53             Min=min(maxf-ret,fee);
    54             fee=dfs(v,Min,t);
    55             e[i].fee-=fee;
    56             e[i^1].fee+=fee;
    57             ret+=fee;
    58             if (ret==maxf) return ret; 
    59         }
    60     }
    61     if (!ret) level[s]=0; //这里是关键 
    62     return ret;
    63 }
    64 int Dinic(int s,int t){
    65     ans=0;
    66     while (bfs(s,t)) ans+=dfs(s,MAX,t);
    67     return ans;
    68 }
    69 int main(){
    70     while (~scanf("%d%d",&n,&m)){
    71         tot=0;
    72         memset(head,-1,sizeof(head));
    73         for (int i=1;i<=n;i++)
    74             scanf("%d%d%d",&x,&y,&z),add(x,y,z);
    75         printf("%d
    ",Dinic(1,m));
    76     }
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    矩阵树定理(Kirchhoff || Laplace)初探——Part 1(无向图计数)
    AC自动机——看似KMP在跑,其实fail在跳
    逆序数模板
    牛客暑期五几何题
    priority_queue()大根堆和小根堆(二叉堆)
    STL中去重函数unique
    简单判断long long 以内的回文数
    素数判断和素数筛(简单方便)
    记忆化递归
    map详细的复习
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7616319.html
Copyright © 2011-2022 走看看