• hdu1532 最大流板子题


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532

    题目给出源点和漏点,还有一些边,要求源与漏之间的最大流,我采用了Edmonds Karp算法,该算法是Ford-Fulkerson算法的一种实现,该算法的关键技术是残留网络和残留网络上的反向边,相当于给了搜索策略一个“反悔”的机会,算法的实行过程是每次都寻找一条源点到漏点的增广路径,算出流的大小,每次寻找到一条路径就进行累加直到无法寻找到一条增广路径。寻找增广路径的一般做法是bfs,用dfs的话迭代的次数可能会非常大,十分消耗速度。在Edmonds Karp算法中,一次增广路径的查找需要消耗O(|E|)的时间,在O(|V||E|)次增广之后最大流就能被找到,所以Edmonds Karp 算法的时间复杂度大约是O(|V||E|^2),复杂度在边多的情况下是非常高的,还有其他如Dinic、ISAP算法等最大流算法,本次我先自写一个EdmondsKarp算法。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define mp(a,b) make_pair((a),(b))
    17 #define P pair<int,int>
    18 #define dbg(args) cout<<#args<<":"<<args<<endl;
    19 #define inf 0x3f3f3f3f
    20 const int maxn=1005;
    21 int n,m,t;
    22 inline int read(){
    23     int ans=0,w=1;
    24     char ch=getchar();
    25     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    26     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    27     return ans*w;
    28 }
    29 int g[maxn][maxn],pre[maxn];//这里的g数组不但保存了正向边的信息还保存了残留网络的信息
    30 int bfs(int src,int sink)
    31 {
    32     int flow[maxn];
    33     mem(pre,-1);
    34     flow[src]=inf;pre[src]=0;//每次从源点发出一股无穷大的水流 
    35      queue<int> q;q.push(src);
    36      while(!q.empty())
    37      {
    38          int u=q.front();
    39          q.pop();
    40          if(u==sink)break;//到达漏点
    41         f(i,1,n)
    42         {
    43             if(i!=src&&pre[i]==-1&&g[u][i]>0)//找到一个不是源点而且没有访问过并且与当前点存在边的结点 
    44             {
    45                 pre[i]=u;
    46                 q.push(i);
    47                 flow[i]=min(flow[u],g[u][i]);//经过i点之后的源的大小更新成为边的大小或者是前驱结点的较小值 
    48             }
    49         }
    50     }     
    51     if(pre[sink]==-1)return -1;//漏点没有被搜索到 
    52     return flow[sink]; 
    53  } 
    54 int maxflow(int src,int sink)
    55 {
    56     int Maxflow=0;
    57     while(1)
    58     {
    59         int flow=bfs(src,sink);
    60         if(flow==-1)break;
    61         int cur=sink;//从漏点开始,一步步向源点回退,更新残余网络 
    62         while(cur!=src)
    63         {
    64             int father=pre[cur];
    65             g[father][cur]-=flow;//从父结点到当前结点的路径上的流量减少flow
    66             g[cur][father]+=flow;//从当前结点到父结点之间增加了一条残余流量
    67             cur=father;//回溯更新参与网络 
    68         }
    69         Maxflow+=flow;
    70     }
    71     return Maxflow;
    72 }
    73 int main()
    74 {
    75     //freopen("input.txt","r",stdin);
    76     //freopen("output.txt","w",stdout);
    77     std::ios::sync_with_stdio(false);
    78     while(scanf("%d%d",&m,&n)!=EOF)
    79     {
    80         mem(g,0);
    81         int u,v,w;
    82         f(i,1,m)
    83         {
    84             u=read(),v=read(),w=read();
    85             g[u][v]+=w;
    86         }
    87         pf("%d
    ",maxflow(1,n));
    88     }
    89 
    90 } 
  • 相关阅读:
    乱码解决
    Collection接口
    YTU EDG Vince Day Training -- 训练赛赛后总结
    Codeforces Round #751 (Div. 2) A. Two Subsequences
    Codeforces Round #750 (Div. 2) C. Grandma Capa Knits a Scarf
    Codeforces Round #745 (Div. 2) B. Diameter of Graph
    Codeforces Round #745 (Div. 2) A. CQXYM Count Permutations
    ytuoj-3328 快速幂
    Codeforces Round #746 (Div. 2) C. Bakry and Partitioning
    Codeforces Round #747 (Div. 2) B. Special Numbers
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12574881.html
Copyright © 2020-2023  润新知