好久没做题了,应该有2个多月了,最近在准备找实习工作,看了几道笔试题,遇到一道网络流的题目,可是做不来,所以又来学下网络流。
这是一道最大流的模板题。
思路:用bfs找最短增广路,求得最短增广路上能通过的最大流量flow,然后该路径上的每条边减去flow,在添加相应的反向边,重复上述操作,知道找不到增广路为止。注意重边!
代码如下:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#define N 205
#define INF 0x3f3f3f3f
using namespace std;
int a[N][N],vis[N],pre[N];
int n,m;//n node ,m edge
struct node
{
int minn,id;
};
queue<node> q;
int bfs()
{
memset(vis,0,sizeof(vis));
memset(pre,0,sizeof(pre));
while(!q.empty()) q.pop();
node temp;
temp.id = 1; temp.minn = INF;
q.push(temp);
vis[1] = 1;
while(!q.empty())
{
node now = q.front();
q.pop();
if(now.id == n) return now.minn;
for(int i = 1; i <= n; i++)
if(!vis[i] && a[now.id][i] > 0)
{
temp.id = i;
temp.minn = min(now.minn,a[now.id][i]);
q.push(temp);
pre[i] = now.id;
vis[i] = 1;
}
}
return -1;
}
int EK()
{
int ans = 0;
while(1)
{
int flow = bfs();
if(flow == -1) break;
ans += flow;
int x = n;
while(x)
{
a[x][ pre[x] ] += flow;
a[ pre[x] ][x] -= flow;
x = pre[x];
}
}
return ans;
}
int main()
{
while(scanf("%d%d",&m,&n) != EOF)
{
int i,x,y,z;
memset(a,0,sizeof(a));
for(i = 0; i < m; i++)
{
scanf("%d%d%d",&x,&y,&z);
a[x][y] += z;
}
printf("%d\n",EK());
}
return 0;
}
/*
13 7
1 2 28
1 4 19
1 3 7
2 5 15
2 3 6
3 4 12
4 2 7
4 5 14
4 7 36
5 7 23
5 6 7
6 3 10
6 7 18
*/