• poj1273 Drainage Ditches (最大流板子


    网络流一直没学,来学一波网络流。

    https://vjudge.net/problem/POJ-1273

    题意:给定点数,边数,源点,汇点,每条边容量,求最大流。

    解法:EK或dinic。

    EK:每次增广用bfs选择一条从源到汇具有最少边数的增广路径,然后找出该路径容量最小的边,就是此次增加的流量,然后沿该路径增加反向边,同时修改每条边的容量,重复上述过程直到找不到增广路(即minFlow = 0)为止。

    dinic: 每次bfs从源点到汇点分层(层数是源点到它最少要经过的边数),然后dfs从源点开始不断向下一层找增广路,碰到汇点说明找到一条,进行增广。然后回溯到点u(u是满足(u,v)容量为0的最上层节点)继续寻找增广路,如果回溯到源点且无法继续往下走dfs结束,然后对残余网络再分层,再dfs直到无法分层,算法结束。

     1 #include<iostream>
     2 #include<queue>
     3 #include<cstring>
     4 using namespace std;
     5 int G[300][300];
     6 int pre[300]; //前驱
     7 bool vis[300];
     8 int n,m; //1是源,m是汇
     9 
    10 inline int solve(){
    11     deque<int> q;
    12     memset(pre,0,sizeof pre);
    13     memset(vis,0,sizeof vis);
    14     pre[1] = 0;
    15     vis[1] = 1;
    16     q.push_back(1);
    17     bool find = false;
    18     while(!q.empty()){
    19         int v = q.front();
    20         q.pop_front();
    21         for(int i=1;i<=m;i++){
    22             if(G[v][i]>0&&vis[i]==0){
    23                 pre[i] = v;
    24                 vis[i] = 1;
    25                 if(i==m){
    26                     find = true;
    27                     q.clear();
    28                     break;
    29                 }
    30                 else q.push_back(i);
    31             }
    32         }
    33     }
    34     if(!find) return 0;
    35     int minFlow = 0x3f3f3f3f;
    36     int v = m;
    37     while(pre[v]){
    38         minFlow = min(minFlow,G[pre[v]][v]);
    39         v = pre[v];
    40     }
    41     v = m;
    42     while(pre[v]){
    43         G[pre[v]][v] -= minFlow;
    44         G[v][pre[v]] += minFlow;
    45         v = pre[v];
    46     }
    47     return minFlow;
    48 }
    49 
    50 int main(){
    51     while(cin>>n>>m){
    52         memset(G,0,sizeof G);
    53         for(int i=0;i<n;i++){
    54             int s,e,c;
    55             cin>>s>>e>>c;
    56             G[s][e] += c;
    57         }
    58         int maxFlow = 0;
    59         int aug;
    60         while(aug=solve())
    61             maxFlow += aug;
    62         cout<<maxFlow<<endl;
    63     }
    64     return 0;
    65 }
    View Code
     1 #include<iostream>
     2 #include<queue>
     3 #include<cstring>
     4 using namespace std;
     5 const int inf = 0x3f3f3f3f;
     6 int G[300][300];
     7 bool vis[300];
     8 int Layer[300];
     9 int n,m; //1是源点,m是汇点
    10 
    11 inline bool countLayer(){
    12     int layer = 0;
    13     deque<int> q;
    14     memset(Layer,0xff,sizeof Layer);
    15     Layer[1] = 0;
    16     q.push_back(1);
    17     while(!q.empty()){
    18         int v = q.front();
    19         q.pop_front();
    20         for(int j=1;j<=m;j++){
    21             if(G[v][j]>0&&Layer[j]==-1){
    22                 Layer[j] = Layer[v]+1;
    23                 if(j==m) return true;
    24                 else q.push_back(j);
    25             }
    26         }
    27     }
    28     return false;
    29 }
    30 
    31 inline int dinic(){
    32     int maxFlow = 0;
    33     deque<int> q;
    34     while(countLayer()){
    35         q.push_back(1);
    36         memset(vis,0,sizeof vis);
    37         vis[1] = 1;
    38         while(!q.empty()){
    39             int nd = q.back();
    40             if(nd==m){
    41                 int minc = inf;
    42                 int minc_vs;
    43                 for(int i=1;i<q.size();i++){
    44                     int vs = q[i-1];
    45                     int ve = q[i];
    46                     if(G[vs][ve]>0){
    47                         if(minc>G[vs][ve]){
    48                             minc = G[vs][ve];
    49                             minc_vs = vs;
    50                         }
    51                     }
    52                 }
    53                 maxFlow += minc;
    54                 for(int i=1;i<q.size();i++){
    55                     int vs = q[i-1];
    56                     int ve = q[i];
    57                     G[vs][ve] -= minc;
    58                     G[ve][vs] += minc;
    59                 }
    60                 while(!q.empty()&&q.back()!=minc_vs){
    61                     vis[q.back()] = 0;
    62                     q.pop_back();
    63                 }
    64             }
    65             else {
    66                 int i;
    67                 for(i=1;i<=m;i++){
    68                     if(G[nd][i]>0&&Layer[i]==Layer[nd]+1&&!vis[i]){
    69                         vis[i] = 1;
    70                         q.push_back(i);
    71                         break;
    72                     }
    73                 }
    74                 if(i>m) q.pop_back();
    75             }
    76         }
    77     }
    78     return maxFlow;
    79 }
    80 
    81 int main(){
    82     while(cin>>n>>m){
    83         memset(G,0,sizeof G);
    84         for(int i=0;i<n;i++){
    85             int s,e,c;
    86             cin>>s>>e>>c;
    87             G[s][e] += c;
    88         }
    89         cout<<dinic()<<endl;
    90     }
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    Spring Boot简明教程之实现Web开发及常用参数获取方式分析
    SpringBoot 简明教程之项目属性配置(三):配置文件优先级及多配置切换
    史上最简单MySQL教程详解(进阶篇)之存储过程(二)
    史上最简单MySQL教程详解(进阶篇)之存储过程(一)
    文字从中间向两边延展
    字符串转化成驼峰命名
    统计字符串字符个数
    while求和(1到100)
    for循环实现乘阶
    递归遍历所有ul下的所有子节点
  • 原文地址:https://www.cnblogs.com/wzgg/p/11357761.html
Copyright © 2020-2023  润新知