码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷 P3376 【模板】网络最大流 题解

时间:2017-11-01 13:44:48      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:nic   math   getch   输入输出   规模   网络   const   tin   位置   

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:https://www.luogu.org/problemnew/show/3376

题目描述

如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。

输入输出格式

输入格式:

第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。

接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)

输出格式:

一行,包含一个正整数,即为该网络的最大流。

输入输出样例

输入样例#1: 
4 5 4 3
4 2 30
4 3 20
2 3 20
2 1 30
1 3 40
输出样例#1: 
50

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=10,M<=25

对于70%的数据:N<=200,M<=1000

对于100%的数据:N<=10000,M<=100000

样例说明:

题目中存在3条路径:

4-->2-->3,该路线可通过20的流量

4-->3,可通过20的流量

4-->2-->1-->3,可通过10的流量(边4-->2之前已经耗费了20的流量)

故流量总计20+20+10=50。输出50。

 

最近学了一下网络流,写个dinic板子ww感谢@ytez jzw的模板

 

AC代码:

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 
 6 const int MAXN = 100005;
 7 const int INF = 1e9;
 8 inline void read(int &x)
 9 {
10     char ch = getchar(),c = ch;x = 0;
11     while(ch < 0 || ch > 9) c = ch,ch = getchar();
12     while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar();
13     if(c == -) x = -x;
14 }
15 
16 int n,m,s,t,u,v,w,cnt,ans,l,r;
17 int head[MAXN<<2],depth[MAXN],q[MAXN];
18 
19 inline int Min(int a,int b)
20 {return a<b?a:b;}
21 
22 inline int other(int x)
23 {return (x%2==0)?(x-1):(x+1);}
24 
25 struct Edge
26 {
27     int f,t,val,nxt;
28 }e[MAXN<<2];
29 
30 void insert(int f,int t,int v)
31 {
32     e[++cnt].f = f,e[cnt].t = t;
33     e[cnt].val = v,e[cnt].nxt = head[f];
34     head[f] = cnt;
35 }
36 
37 bool bfs()
38 {
39     memset(depth,-1,sizeof(depth));
40     l = 1,r = 1;
41     q[++r] = s,depth[s] = 0;
42     while(l <= r)
43     {
44         int now = q[l++];
45         if(now == t) continue;
46         for(int i = head[now];i;i = e[i].nxt)
47         {
48             if(!e[i].val) continue;
49             int to = e[i].t;
50             if(depth[to] == -1)
51             {
52                 depth[to] = depth[now]+1;
53                 q[++r] = to;
54             }
55         }
56     }
57     return depth[t] != -1;
58 }
59 
60 int dfs(int now,int flow)
61 {
62     if(now == t) return flow;
63     int flowed = 0;
64     for(int i = head[now];i;i = e[i].nxt)
65     {
66         int to = e[i].t;
67         if(flow == flowed) break;
68         if(e[i].val == 0) continue;
69         
70         if(depth[to] == depth[now]+1)
71         {
72             int new_flow = dfs(to,Min(e[i].val,flow-flowed));
73             flowed += new_flow;
74             e[i].val -= new_flow;
75             e[other(i)].val += new_flow;
76         }
77     }
78 
79     return flowed;
80 }
81 
82 int main()
83 {
84     read(n),read(m);
85     read(s),read(t);
86     for(int i = 1;i <= m;++ i)
87     {
88         read(u),read(v),read(w);
89         insert(u,v,w);
90         insert(v,u,0);
91     }
92     while(bfs())
93         ans += dfs(s,INF);
94 
95     printf("%d\n",ans);
96     return 0;
97 }

 

更新*1   运行速度688ms --> 252ms

洛谷 P3376 【模板】网络最大流 题解

标签:nic   math   getch   输入输出   规模   网络   const   tin   位置   

原文地址:http://www.cnblogs.com/shingen/p/7763876.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!