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\n",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\n",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\n",k++,dinic());
103     }
104 }

 

转载于:https://www.cnblogs.com/pblr/p/5558578.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值