OJ 1449. Maximum flow
题目描述
给定一张源为 1,汇为 n的网络,求 1到 n的最大流。
Input
请从 stdin 读入。
输入第一行为两个正整数 n, m
(
2
≤
n
,
m
≤
200
)
(2 \leq n, m \leq 200)
(2≤n,m≤200)。
接下来 m 行,第 i 行为用空格隔开的整数
u
i
,
v
i
,
c
i
(
1
≤
u
i
,
v
i
≤
n
,
1
≤
c
i
≤
200
)
u_i, v_i, c_i (1 \leq u_i, v_i \leq n, 1 \leq c_i \leq 200)
ui,vi,ci(1≤ui,vi≤n,1≤ci≤200)表示一条
u
i
u_i
ui到
v
i
v_i
vi,容量为
c
i
c_i
ci的单向边。
输入可能有重边和自环。
Output
请输出到 stdout 中。
输出一行,包含一个整数,表示最大流的流量。
Sample Input
4 4
1 2 1
2 3 2
1 3 1
3 4 3
2 2
1 2 1
1 2 1
3 1
1 2 1
2 3
1 2 1
1 2 1
2 1 1
7 14
1 2 5
1 3 6
1 4 5
2 3 2
2 5 3
3 2 2
3 4 3
3 5 3
3 6 7
4 6 5
5 6 1
6 5 1
5 7 8
6 7 7
Sample Output
2
2
0
2
14
Constraints
Time Limit: 1s
Memory Limit: 512MB
Solution
使用 Edmonds-Karp algorithm 通过构造剩余网络来解决。
时间复杂度为O(
∣
V
∣
∣
E
∣
2
|V||E|^2
∣V∣∣E∣2),
∣
V
∣
|V|
∣V∣为图中点数,
∣
E
∣
|E|
∣E∣为图中边数。
Code
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
vector<vector<int>>g;
vector<int> pre;
vector<int> a;
int n, m;
int EK(){
int flow=0;
queue<int> q;
while(true){
q.push(1);
a.assign(n+1,0);
a[1]=1000;//源点流量无穷大
while(!q.empty()){
int vex=q.front();
q.pop();
for(int i=1;i<n+1;i++){
if(g[vex][i]>0 && a[i]==0){
a[i]=min(a[vex],g[vex][i]);
q.push(i);
pre[i]=vex;
}
}
}
if(a[n]==0){
return flow;
}
flow+=a[n];
for(int i=n;i!=1;i=pre[i]){//更新剩余网络
g[pre[i]][i]-=a[n];
g[i][pre[i]]+=a[n];
}
}
}
int main()
{
cin>>n>>m;
g.assign(n+1,vector<int>(n+1));
pre.assign(n+1,0);
int u, v, c;
for(int i=0;i<m;i++){
cin>>u>>v>>c;
g[u][v]+=c;
}
cout<<EK();
return 0;
}