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
  • 相关阅读:
    自己写的一个读取execl的帮助类
    手动获取spring的ApplicationContext和bean对象
    前端开发不容错过的jQuery图片滑块插件(转)
    细说HTML元素的隐藏和显示
    DIV+CSS布局重新学习之使用A标签和CSS制作按钮
    opencv2函数学习之flip:实现图像翻转
    DWZ中Tree树形菜单的treeCheck如何获取返回值解决方案
    DWZ中刷新dialog的方案解决
    DWZ与KindEditor编辑器的整合
    ViewModel在MVC3中的应用:实现多字段表格的部分更新
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7616319.html
Copyright © 2011-2022 走看看