【网络流#3】hdu 1532 - Dinic模板题

输入为m,n表示m条边,n个结点

记下来m行,每行三个数,x,y,c表示x到y的边流量最大为c

这道题的模板来自于网络

http://blog.csdn.net/sprintfwater/article/details/7913061

算法时间复杂度o(V^2*E)

 

关于这个模板:
Edge为前向星的边数,所以需要初始化Edge和head数组,其中head数组应初始化为-1

int dinic(int n,int s,int t);
n表示有n个点,这个版无所谓点从0开始还是从1开始,s表示源点,t表示汇点
很好的一个是,这个版的DFS使用的是模拟栈,防止爆栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<sstream>
#define MAXN 200
#define MAXM 400
#define INF (1<<30)
#define eps 0.000001
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
using namespace std;
int i,j,k,n,m,x,y,T,num,w;
 
const int inf = 0x3f3f3f3f;
struct edgenode
{
    int from,to,next;
    int cap;
}edge[MAXM];
int Edge,head[MAXN],ps[MAXN],dep[MAXN];
 
void addedge(int x,int y,int c)
{
    edge[Edge].from=x;
    edge[Edge].to=y;
    edge[Edge].cap=c;
    edge[Edge].next=head[x];
    head[x]=Edge++;
     
    edge[Edge].from=y;
    edge[Edge].to=x;
    edge[Edge].cap=0;
    edge[Edge].next=head[y];
    head[y]=Edge++;
}
 
int dinic(int n,int s,int t)
{
    int tr,flow=0;
    int i,j,k,l,r,top;
    while(1){
        memset(dep,-1,(n+1)*sizeof(int));
        for(l=dep[ps[0]=s]=0,r=1;l!=r;)//BFS部分,将给定图分层
        {
            for(i=ps[l++],j=head[i];j!=-1;j=edge[j].next)
            {
                if (edge[j].cap&&-1==dep[k=edge[j].to])
                {
                    dep[k]=dep[i]+1;ps[r++]=k;
                    if(k==t)
                    {
                        l=r;
                        break;
                    }
                }
            }
        }
        if(dep[t]==-1)break;
         
        for(i=s,top=0;;)//DFS部分
        {
            if(i==t)//当前点就是汇点时
            {
                for(k=0,tr=inf;k<top;++k)
                    if(edge[ps[k]].cap<tr)tr=edge[ps[l=k]].cap;
                     
                for(k=0;k<top;++k)
                    edge[ps[k]].cap-=tr,edge[ps[k]^1].cap+=tr;
                     
                flow+=tr;
                i=edge[ps[top=l]].from;
            }
             
            for(j=head[i];j!=-1;j=edge[j].next)//找当前点所指向的点
                if(edge[j].cap&&dep[i]+1==dep[edge[j].to]) break;
                 
            if(j!=-1)
            {
                ps[top++]=j;//当前点有所指向的点,把这个点加入栈中
                i=edge[j].to;
            }
            else
            {
                if (!top) break;//当前点没有指向的点,回溯
                dep[i]=-1;
                i=edge[ps[--top]].from;
            }
        }
    }
    return flow;
}
 
int main()
{
    int T,cas,m,s,t,n,maxflow,i;
    int x,y,c;
    double ans;
    while(~scanf("%d%d",&m,&n))
    {  
        memset(head,-1,sizeof(head));
        Edge=0;
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&c);
            addedge(x,y,c);
        }
        printf("%d\n",dinic(n,1,n));
    }
    return 0;
}

  

posted @   zhyfzy  阅读(412)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示