【网络流#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; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步