zoukankan      html  css  js  c++  java
  • poj 1273 Drainage Ditches (最大流入门)

     1 /******************************************************************
     2  题目:     Drainage Ditches(POJ 1273)
     3  链接:     http://poj.org/problem?id=1273
     4  题意:     现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条
     5             水渠,给出这n条水渠所连接的池塘和所能流过的水量,求水
     6             渠中所能流过的水的最大容量.水流是单向的。
     7  算法:     最大流之增广路(入门)
     8  算法思路: 不断用BFS找通路,没每找一条路,记录这条路的最小流,再
     9             给这条路上的所有流量减去这个最小值。
    10 *********************************************************************/
    11 #include<cstdio>
    12 #include<iostream>
    13 #include<cstring>
    14 #include<algorithm>
    15 #include<queue>
    16 using namespace std;
    17 
    18 const int mx=222;
    19 int cap[mx][mx];        ///两个端点的流量。
    20 int flow[mx][mx];       ///两个端点已用的流量。
    21 int a[mx],father[mx];
    22 int m,n;
    23 
    24 int bfs()
    25 {
    26     queue<int>q;
    27     int ans=0;
    28     father[1]=-1;
    29     while (1)
    30     {
    31         memset(a,0,sizeof(a));
    32         a[1]=1000000000;
    33         q.push(1);
    34         ///找增广路
    35         while (!q.empty())
    36         {
    37             int u=q.front();
    38             q.pop();
    39             for (int v=2;v<=n;v++)
    40             {
    41                 if (!a[v]&&cap[u][v]>flow[u][v])
    42                 {
    43                     father[v]=u;
    44                     q.push(v);
    45                     a[v]=min(a[u],cap[u][v]-flow[u][v]);
    46                 }
    47             }
    48         }
    49         if (a[n]==0) return ans;
    50         for (int u=n;father[u]!=-1;u=father[u])
    51         {
    52             flow[u][father[u]]-=a[n];            ///更新反向流量        
    53             flow[father[u]][u]+=a[n];           ///更新正向流量
    54         }
    55         ans+=a[n];                           
    56     }
    57 }
    58 
    59 int main()
    60 {
    61     while (~scanf("%d%d",&m,&n))
    62     {
    63         memset(cap,0,sizeof(cap));
    64         memset(flow,0,sizeof(flow));
    65         int u,v,w;
    66         while (m--)
    67         {
    68             scanf("%d%d%d",&u,&v,&w);
    69             cap[u][v]+=w;
    70         }
    71         int ans=bfs();
    72         printf("%d
    ",ans);
    73     }
    74 }
     1 /*********************************************************
     2 题目:        Drainage Ditches(poj 1273)
     3 算法:      最大流之dinic(入门)
     4 算法思想:  dinic的主要思想是层次图和阻塞流,只保留每个节点
     5              出发到下一个层次的弧,得到的图就叫层次图。阻塞
     6             流就是不考虑反向弧时的极大流。先用bfs分层,再计
     7             算阻塞流,不断从复这两步,直到找不到阻塞流结束。
     8 ************************************************************/
     9 #include<cstdio>
    10 #include<cstring>
    11 #include<algorithm>
    12 #include<iostream>
    13 #include<queue>
    14 using namespace std;
    15 
    16 const int mx=222;
    17 int map[mx][mx];
    18 int d[mx];
    19 int m,n;
    20 
    21 ///分层
    22 int bfs()
    23 {
    24     queue<int>q;
    25     memset(d,0,sizeof(d));
    26     q.push(1);
    27     while (!q.empty())
    28     {
    29         int u=q.front();
    30         q.pop();
    31         for (int v=2;v<=n;v++)
    32         {
    33             if (!d[v]&&map[u][v]>0)
    34             {
    35                 d[v]=d[u]+1;
    36                 q.push(v);
    37             }
    38         }
    39     }
    40     return d[n];
    41 }
    42 
    43 ///计算阻塞流
    44 int dfs(int u,int w)
    45 {
    46     if (u==n||w==0) return w;
    47     int ans=0;
    48     int temp;
    49     for (int v=2;v<=n;v++)
    50     {
    51         if (map[u][v]>0&&d[u]==d[v]-1)
    52         {
    53             int temp=dfs(v,min(w,map[u][v]));
    54             ans+=temp;
    55             map[u][v]-=temp;    ///正向更新
    56             map[v][u]+=temp;    ///方向更新
    57             w-=temp;            ///从v流出的流量不能大于w。
    58         }
    59     }
    60     return ans;
    61 }
    62 
    63 ///dinic算法
    64 int dinic()
    65 {
    66     int ans=0;
    67     while (bfs())
    68     ans+=dfs(1,1000000000);
    69     return ans;
    70 }
    71 
    72 int main()
    73 {
    74     while (~scanf("%d%d",&m,&n))
    75     {
    76         memset(map,0,sizeof(map));
    77         int u,v,w;
    78         while (m--)
    79         {
    80             scanf("%d%d%d",&u,&v,&w);
    81             map[u][v]+=w;
    82         }
    83         printf("%d
    ",dinic());
    84     }
    85 }
  • 相关阅读:
    vb中5种打开文件夹浏览框的方法总结(转)
    js 日期
    正则表达式
    HTML中meta的作用
    Java操作ElasticSearch
    Elastic安装
    Elasticsearch基本操作
    ubootfs2410移植(转)
    内核驱动系列字符设备驱动流程
    linux 内核移植
  • 原文地址:https://www.cnblogs.com/pblr/p/5557479.html
Copyright © 2011-2022 走看看