zoukankan      html  css  js  c++  java
  • hdu 3549 Flow Problem (最大流入门题)

    增广路:

     1 /*************************************************************
     2 题目:       Flow Problem(HDU 3549)
     3 链接:       http://acm.hdu.edu.cn/showproblem.php?pid=3549
     4 题意:       给一个单向图,求从1到n的最大流
     5 算法:      最大流之增广路(入门)
     6 算法思想:  不断用BFS找通路,没每找一条路,记录这条路的最小流,
     7             再给这条路上的所有流量减去这个最小值。
     8 **************************************************************/
     9 #include<iostream>
    10 #include<cstdio>
    11 #include<cstring>
    12 #include<algorithm>
    13 #include<queue>
    14 using namespace std;
    15 
    16 int cap[20][20];
    17 int a[20],father[20];
    18 int n,m;
    19 
    20 void Init()
    21 {
    22     memset(cap,0,sizeof(cap));
    23     memset(a,0,sizeof(a));
    24 }
    25 
    26 int bfs()
    27 {
    28     queue<int>q;
    29     int ans=0;
    30     while (1)
    31     {
    32         while (!q.empty()) q.pop();
    33         memset(a,0,sizeof(a));
    34         a[1]=10000000;
    35         q.push(1);
    36         father[1]=-1;
    37         while (!q.empty())
    38         {
    39             int u=q.front();
    40             q.pop();
    41             for (int v=2;v<=n;v++)
    42             {
    43                 if (!a[v]&&cap[u][v]>0)
    44                 {
    45                     q.push(v);
    46                     father[v]=u;
    47                     a[v]=min(a[u],cap[u][v]);
    48                 }
    49             }
    50         }
    51         if (!a[n]) return ans;
    52         for (int u=n;father[u]!=-1;u=father[u])
    53         {
    54             cap[u][father[u]]+=a[n];
    55             cap[father[u]][u]-=a[n];
    56         }
    57         ans+=a[n];
    58 
    59     }
    60 }
    61 
    62 int  main()
    63 {
    64     int t,k=1;
    65     scanf("%d",&t);
    66     while (t--)
    67     {
    68         scanf("%d%d",&n,&m);
    69         Init();
    70         int u,v,w;
    71         while (m--)
    72         {
    73             scanf("%d%d%d",&u,&v,&w);
    74             cap[u][v]+=w;
    75         }
    76         printf("Case %d: %d
    ",k++,bfs());
    77     }
    78 }

    dinic:

     1 /***************************************************************
     2 算法:      最大流之dinic(入门)
     3 算法思想:  dinic的主要思想是层次图和阻塞流,只保留每个节点
     4              出发到下一个层次的弧,得到的图就叫层次图。阻塞
     5             流就是不考虑反向弧时的极大流。先用bfs分层,再计
     6             算阻塞流,不断从复这两步,直到找不到阻塞流结束。
     7 ***************************************************************/
     8 #include<iostream>
     9 #include<cstdio>
    10 #include<cstring>
    11 #include<algorithm>
    12 #include<queue>
    13 using namespace std;
    14 
    15 int cap[20][20];
    16 int d[20];
    17 int n,m;
    18 
    19 int bfs()
    20 {
    21     queue<int>q;
    22     memset(d,0,sizeof(d));
    23     q.push(1);
    24     while (!q.empty())
    25     {
    26         int u=q.front();
    27         q.pop();
    28         for (int v=2;v<=n;v++)
    29         {
    30            if (!d[v]&&cap[u][v]>0)
    31            {
    32                q.push(v);
    33                d[v]=d[u]+1;
    34            }
    35         }
    36     }
    37     return d[n];
    38 }
    39 
    40 int dfs(int u,int w)
    41 {
    42     if (u==n||w==0) return w;
    43     int ans=0;
    44     for (int v=2;v<=n;v++)
    45     {
    46         if (cap[u][v]>0&&d[u]==d[v]-1)
    47         {
    48             int temp=dfs(v,min(w,cap[u][v]));
    49             cap[u][v]-=temp;
    50             cap[v][u]+=temp;
    51             w-=temp;
    52             ans+=temp;
    53         }
    54     }
    55     return ans;
    56 }
    57 
    58 int dinic()
    59 {
    60     int ans=0;
    61     while (bfs()) ans+=dfs(1,100000000);
    62     return ans;
    63 }
    64 
    65 int main()
    66 {
    67     int t,k=1;
    68     scanf("%d",&t);
    69     while (t--)
    70     {
    71         scanf("%d%d",&n,&m);
    72         memset(cap,0,sizeof(cap));
    73         int u,v,w;
    74         while (m--)
    75         {
    76             scanf("%d%d%d",&u,&v,&w);
    77             cap[u][v]+=w;
    78         }
    79         printf("Case %d: %d
    ",k++,dinic());
    80     }
    81 }

    dinic之邻接表建图:

      1 /************************************************
      2 算法:  最大流之dinic(邻接表建图)
      3 *************************************************/
      4 
      5 #include<iostream>
      6 #include<cstdio>
      7 #include<cstring>
      8 #include<algorithm>
      9 #include<queue>
     10 using namespace std;
     11 
     12 const int mx=1005;
     13 struct Eage
     14 {
     15     int u,v;
     16     int next,cap;
     17 };
     18 Eage eage[mx*2];
     19 int head[mx];
     20 int d[mx];
     21 int pos;
     22 int n,m;
     23 
     24 void Init()
     25 {
     26     memset(head,-1,sizeof(head));
     27     pos=0;
     28 }
     29 
     30 void add(int u,int v,int w)
     31 {
     32     eage[pos].v=v;
     33     eage[pos].cap=w;
     34     eage[pos].next=head[u];
     35     head[u]=pos++;
     36 }
     37 
     38 int bfs()
     39 {
     40     queue<int>q;
     41     memset(d,0,sizeof(d));
     42     d[1]=1;
     43     q.push(1);
     44     while (!q.empty())
     45     {
     46         int u=q.front();
     47         q.pop();
     48         for (int i=head[u];i!=-1;i=eage[i].next)
     49         {
     50             int v=eage[i].v;
     51             if (!d[v]&&eage[i].cap>0)
     52             {
     53                 d[v]=d[u]+1;
     54                 q.push(v);
     55             }
     56         }
     57     }
     58     return d[n];
     59 }
     60 
     61 int dfs(int u,int w)
     62 {
     63     if (u==n||w==0) return w;
     64     int ans=0;
     65     for (int i=head[u];i!=-1;i=eage[i].next)
     66     {
     67         int v=eage[i].v;
     68         if (d[u]==d[v]-1&&eage[i].cap>0)
     69         {
     70             int temp=dfs(v,min(w,eage[i].cap));
     71             eage[i].cap-=temp;
     72             eage[i^1].cap+=temp;
     73             w-=temp;
     74             ans+=temp;
     75         }
     76     }
     77     return ans;
     78 }
     79 
     80 int dinic()
     81 {
     82     int ans=0;
     83     while (bfs()) ans+=dfs(1,10000000);
     84     return ans;
     85 }
     86 
     87 int main()
     88 {
     89     int t,k=1;
     90     scanf("%d",&t);
     91     while (t--)
     92     {
     93         Init();
     94         scanf("%d%d",&n,&m);
     95         int u,v,w;
     96         while (m--)
     97         {
     98             scanf("%d%d%d",&u,&v,&w);
     99             add(u,v,w);
    100             add(v,u,0);
    101         }
    102         printf("Case %d: %d
    ",k++,dinic());
    103     }
    104 }
  • 相关阅读:
    base.View.OpenParameter.CreateFrom打开历史单据的值是default
    创建日期时间大于启动日期时间
    下拉列表不显示空白选项的原因
    复制、下推、选单时计算类的实体服务规则不会执行
    选单返回数据以后会执行的事件方法
    判断单据体是否录入行
    供应商协同平台
    .net core获取运行时文件绝对路径
    gmock函数参数输出 备忘录
    リバース 終章
  • 原文地址:https://www.cnblogs.com/pblr/p/5558578.html
Copyright © 2011-2022 走看看