最大流--解法1

默认节点s=0,t=n-1

数据输入样例:

点数 边数

边...

6 10
0 1 16
0 2 13
1 2 10
1 3 12
2 1 4
2 4 14
3 2 9
3 5 20
4 3 7
4 5 4

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstdlib>

using namespace std;

int FordFullkerson(vector<vector<int> >& cf, vector<vector<int> >& f)
{
    int n = cf.size();
    int maxFlow = 0;
    while( true )
    {
	// serach augmenting path
	vector<int> cfp(n, 0);
	vector<int> path(n, 0);
	queue<int> q;

	int s = 0;
	q.push( s );
	cfp[s] = 0xffff;

	while( !q.empty() )
	{
	    int cur = q.front();
	    if( cur == n - 1 )
		break;
	    q.pop();

	    for(int i = 0; i < n; ++i)
	       if( !cfp[i] && cf[cur][i] )	
	       {
		   cfp[i] = min(cf[cur][i], cfp[cur]);
		   path[i] = cur;
		   q.push( i );
	       }
	}

	if( q.empty() ) // no augmenting path
	{
	    // note that when f is max flow, any cut is mini cut!!!--- this is wrong!! Mark
	    cout << "S: " ;
	    for(int i = 0; i < n; ++i)
		if( cfp[i] )
		    cout << i << " ";
	    cout << endl;
	    cout << "T: ";
	    for(int i = 0; i < n; ++i)
		if( !cfp[i] )
		    cout << i << " ";
	    cout << endl;

	    break;
	}

	cout << "cfp = " << cfp[n-1] << endl;

	int i = n - 1;
	while( path[i] != i )
	{
	    int u = path[i], v = i;
	    cf[u][v] -= cfp[n-1];
	    cf[v][u] += cfp[n-1];

	    f[u][v] += cfp[n-1];
	    f[v][u] -= cfp[n-1];

	    i = path[i];
	}

	maxFlow += cfp[n-1];
    }

    return maxFlow;
}
void ReadNetwork()
{
    int n, m;
    while( cin >> n >> m )
    {
	vector<vector<int> > cf(n);
	for(int i = 0; i < n; ++i)
	    cf[i].assign(n, 0);

	for(int i = 0; i < m; ++i)
	{
	    int u, v, w;
	    cin >> u >> v >> w;
	    cf[u][v] = w;
	}

	vector<vector<int> > f(n);
	for(int i = 0; i < n; ++i)
	    f[i].assign(n, 0);
	int maxFlow = FordFullkerson(cf, f);
	cout << "maxFlow = " << maxFlow << endl;
    }
}
int main()
{
    freopen("graph.data", "r", stdin);
    ReadNetwork();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值