Problem Description
Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.
Input
The first line of input contains an integer T, denoting the number of test cases.
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)
Output
For each test cases, you should output the maximum flow from source 1 to sink N.
Sample Input
2 3 2 1 2 1 2 3 1 3 3 1 2 1 2 3 1 1 3 1
Sample Output
Case 1: 1 Case 2: 2
题解:就是求最大流问题。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#define mem(a) memset(a,0,sizeof(a));
using namespace std;
const int INF = 0x3fffffff;
struct Node
{
int to;
int w;
Node(int a,int b)
{
to = a;
w = b;
}
};
//vector<Node> vec[1003];
int surplus[1003][1003];
int pre[1003]; //路径
int flow[1003]; //保存源点到当前点的最小流量
queue<int> q;
int bfs(int s,int d)
{
while(!q.empty()) //每次都是从源点找到汇点的路径,上一次的清空
{
q.pop();
}
q.push(s);
memset(pre,-1,sizeof(pre)); //每次的前驱都得初始化
while(!q.empty())
{
int t = q.front();
q.pop();
for(int i = 1;i <= d;i++) //广搜
{
if(surplus[t][i] > 0 && pre[i] == -1) //有流量可以通过并且没访问过
{
flow[i] = min(surplus[t][i],flow[t]);
pre[i] = t;
if(i == d) //找到汇点
{
return flow[d];
}
q.push(i);
}
}
}
return -1;
}
int maxFlow(int s,int d)
{
int res = 0;
int plus = 0;
pre[s] = s;
flow[s] = INF; //源点为最大值,后面要求最小值
while((plus = bfs(s,d)) != -1) //找到增广路径,就是源点到汇点的路径
{
res += plus; //把该次找到的流量加到最大流
for(int i = d;i != s;i = pre[i])
{
surplus[pre[i]][i] -= plus; //该路径的流量已经通过了plus,减去就是剩下的流量
surplus[i][pre[i]] += plus; //上一条路径也许还有其他路可以走,加上之后,我可
//以走上次没有走过的那条,这里太重要了
}
}
return res;
}
int main()
{
int T;
cin>>T;
int t = 0;
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
mem(surplus);
for(int i = 0;i < m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
surplus[u][v] += w;
}
printf("Case %d: ",++t);
printf("%d\n",maxFlow(1,n));
}
return 0;
}
5667

被折叠的 条评论
为什么被折叠?



