题目大意: 网络流入门题,给出无向图,求出无向图最大流量。
解题策略: 1,初学网络流,用的是最基本的EK算法,朴素BFS不断求最短增广路。
2,无向图求最大流与平常的有向图求最大流的区别在于对“后退边”的处理,术语叫“后退弧”
暂发现wa点有:
(1) 用DFS求最大流应是其他算法,“后退弧”要加上每次从残留网络中增广路的可行流量(可理解为增光路最短边);
(2) 网络的容量是可以累加的,比如第一次输入“1 3 20”, g[1][3] = g[3][1] = 20, 接下来输入“1 3 10”, g[1][3] = g[3][1] = ? 20+10=30;
3,默默啃网络流……
/*
UVA 820 Internet Bandwidth
Algorothm: bfs实现EK算法
AC by J_Dark
ON 2013/4/27
Time 0.032s
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <climits>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 110;
int g[maxn][maxn], nodeNum, pathNum, pre[maxn];
int start, end, count1=0;
void Input(){
cin >> start >> end >> pathNum;
memset(g, 0, sizeof(g));
int u, v, Capacity;
for(int i=0; i<pathNum; i++){
cin >> u >> v >> Capacity;
g[u][v] = g[v][u] += Capacity;
}
}
bool EK_BFS(){
queue<int> q;
bool visited[maxn];
memset(visited, false, sizeof(visited));
memset(pre, -1, sizeof(pre));
//
q.push(start);
visited[start] = true;
while(!q.empty())
{
int e = q.front(); //当队列头结点为汇点,判定找到一条增广路
if(e == end) return true;
q.pop();
for(int i=1; i<=nodeNum; i++){
if(g[e][i] && !visited[i]){ //当边容量非零,且未被增广标记
visited[i] = true;
pre[i] = e; //记录前驱
q.push(i);
}
}
}
return false;
}
void EK_Max_Flow(){
int u, tempFlow, maxFlow = 0;
while(EK_BFS())
{
tempFlow = INT_MAX;
u = end;
while(pre[u] != -1)
{
tempFlow = min(tempFlow, g[pre[u]][u]);
u = pre[u];
}
maxFlow += tempFlow;
//cout << maxFlow << endl;
u = end;
while(pre[u] != -1)
{
g[pre[u]][u] -= tempFlow;
g[u][pre[u]] += tempFlow;
u = pre[u];
}
}
cout << "Network " << ++count1 << endl;
cout << "The bandwidth is " << maxFlow << "." << endl << endl;
}
///
int main(){
while(cin >> nodeNum && nodeNum)
{
Input();
EK_Max_Flow();
}
return 0;
}