[Luogu] P3376 模板-网络流-最大流

题目描述

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

输入输出格式

输入格式:

 

第一行包含四个正整数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。

 

分析

这是一个单纯的题目,优化都不用

= =然而我是对着刘汝佳写过去的

网络流还是推荐紫书

 

代码

 1 //事先声明,这份代码并不是原创,只是将刘汝佳的进行风格转化
 2 //数组模拟版本邻接表= =刘汝佳写的虽然简练但是我不是很习惯
 3 #include<cstdio>
 4 #include<iostream>
 5 #include<queue>
 6 #include<cstring>
 7 #define maxn 10000000
 8 using namespace std;
 9 
10 int inf = 2139999999;
11 
12 struct edge{
13     int from,u,v,cup,flow;
14 }e[maxn];
15 
16 int tot = 2,first[maxn*4];
17 void insert(int u,int v,int ccup){
18     e[tot].from = first[u];
19     e[tot].u = u;
20     e[tot].v = v;
21     e[tot].cup = ccup;
22     e[tot].flow = 0;
23     first[u] = tot;
24     tot++;
25     
26     e[tot].from = first[v];
27     e[tot].u = v;
28     e[tot].v = u;
29     e[tot].cup = e[tot].flow = 0;
30     first[v] = tot;
31     tot++;
32 }
33 
34 int pre[maxn],s,t,a[maxn],n,m;
35 int maxflow(int s,int t){
36     
37     int flow = 0;
38     while(true){
39 //        cout << "gua!  ";
40         memset(a,0,sizeof(a));
41         queue<int> Q;
42         Q.push(s);
43         a[s] = inf;
44         while(!Q.empty()){
45 //            cout << "Meow!  ";
46             int p = Q.front(); Q.pop();
47             
48             for(int i = first[p];i;i = e[i].from){
49                 edge &E = e[i];
50                 if(!a[E.v] && E.flow < E.cup){
51                     pre[E.v] = i;
52                     a[E.v] = min(a[p],E.cup-E.flow);
53                     Q.push(E.v);
54                 }
55             }
56             
57             if(a[t]) break;
58         }
59         
60         if(!a[t]) break;
61         
62         for(int u = t;u != s;u = e[pre[u]].u){
63             e[pre[u]].flow += a[t];
64             e[pre[u]^1].flow -= a[t];
65         }
66         
67         flow += a[t];
68     }
69     
70 //    for(int i = 0;i <= n;i++){
71 //        printf("%d ",a[i]);
72 //    }cout << endl;
73     
74     return flow;
75 }
76 
77 int main(){
78     scanf("%d%d%d%d",&n,&m,&s,&t);
79     
80     for(int i = 1;i <= m;i++){
81         int u,v,ccup;
82         scanf("%d%d%d",&u,&v,&ccup);
83         insert(u,v,ccup);
84     } 
85     
86     cout << maxflow(s,t);
87     
88 //    for(int i = 0;i <= tot;i++){
89 //        printf("%d %d %d %d %d\n",e[i].from,e[i].u,e[i].v,e[i].cup,e[i].flow);
90 //    }
91     
92     return 0;
93 } 
心情仍然奇差无比

 

posted @ 2017-08-25 23:44  Leviaton  阅读(194)  评论(0编辑  收藏  举报