您的位置:首页 > 理论基础 > 计算机网络

网络流算法之一

2012-03-08 23:24 134 查看
1. Edmonds-karp 算法

用广度优先搜索来实现对增广路径p的计算,即如果增广入径是残留网络中从(s到t的最短路径,就能改进FORD-FULKERSON的界,

称Ford-Fulkerson方法的这种实现为Edmonds-karp算法,时间复杂度为O(VE^2);

HDU 3549

View Code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <deque>

using namespace std;
deque<int>q;
int cap[16][16]; //存储网络容量C,原来数组开了1000,TLE了N久
int flow[16][16]; //存储流过容量f
int e[16]; //每个顶点余流
int h[16]; //每个定点高度
int visit[16]; //标记顶点
int N,vertix;

int Scan()
{
int res = 0 , ch ;
while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) )
{
if( ch == EOF )  return 1 << 30 ;
}
res = ch - '0' ;
while( ( ch = getchar() ) >= '0' && ch <= '9' )
res = res * 10 + ( ch - '0' ) ;
return res ;
}

const int inf = 0x7f7f7f7f;

int min( int x, int y)
{
return x < y ? x : y;
}

void Push( int u, int v)
{
int x = cap[u][v] - flow[u][v];
if( h[u] == h[v] + 1 && e[u] > 0 && x > 0 )
{
x = min(e[u], x);
flow[u][v] += x;
flow[v][u] = -flow[u][v];
e[u] -= x;
e[v] += x;
if( !visit[v] && v != 1 && v != vertix )
{
q.push_back( v );
visit[v] = 1;
}
}
}

void Relable(int u )
{
int H = inf;
if( e[u] > 0 && u != 1 && u != vertix )
{
for( int i = 1; i <= vertix; i++)
{
int x = cap[u][i] - flow[u][i];
if(x > 0 && h[i] < H)
{
H = h[i];
}
}
if( h[u] <= H)
{
h[u] = H + 1;
visit[u] = 1;
q.push_back( u );
}
}
}

void Initialize_Preflow( )
{
memset(h, 0, sizeof(h));
memset(e, 0, sizeof(e));
memset(flow, 0,sizeof(flow));
memset(visit,0, sizeof(visit));
h[1] = vertix;
visit[1] = 1;
q.push_back( 1 );
for( int i = 1; i <= vertix; i++)
{
if (cap[1][i])
{
flow[1][i] = cap[1][i];
flow[i][1] = -cap[1][i];
e[i] = cap[1][i];
e[1] = e[1] - cap[1][i];
visit[i] = 1;
q.push_back(i);
}
}
}

void solve(int x )
{
while( !q.empty() )
{
int u = q.front( );
visit[u] = 0;
q.pop_front( );
for( int i = 1; i <= vertix; i++)
{
Push(u, i);
}
Relable( u );
}
int ans = 0;
for( int i = 1; i <= vertix; i++)
{
ans += flow[1][i];
}
printf("Case %d: %d\n", x, ans);
}

int main( )
{
int a, b, c, l = 0, T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&vertix, &N);
l++;
q.clear();
memset(cap, 0, sizeof(cap));
for( int i = 1; i <= N; i++)
{
//scanf("%d%d%d",&a,&b, &c);
a = Scan();
b = Scan();
c = Scan();
cap[a][b] += c;
}
Initialize_Preflow( );
solve(l);
}
return 0;
}
/*
6
6
10
1 2 16
1 3 13
2 3 10
3 2 4
2 4 12
4 3 9
3 5 14
5 4 7
5 6 4
4 6 20
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: