您的位置:首页 > 其它

POJ 1273

2014-11-23 23:52 176 查看
一道裸的网络流求最大流问题

//一般增广路,每次不断在生于网络找层次网络,直到找不到说明已找到最大流量
#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
const int N = 210;
using namespace std;

int n,m;
int cap

, flow

, lev
;
int pre
;//回溯标记

bool find_levelnet()
{
memset(pre , -1 , sizeof(pre));
queue<int> q;
q.push(1);
pre[1] = 0;
memset(lev , 0x3f , sizeof(lev));
lev[1] = 1;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i=1 ; i<=n ; i++){
int tmp = cap[u][i] - flow[u][i];
if(tmp && lev[i] > lev[u]+1){
lev[i] = lev[u]+1;
pre[i] = u;
q.push(i);
}
}
}
if(lev
> n) return false;
return true;
}

int get_min_flow()
{
int minn = 0x3f3f3f3f;
for(int i = n ; i!=1 ; i=pre[i]){
int u = pre[i];
minn = min(minn , cap[u][i] - flow[u][i]);
}
return minn;
}

void update(int d)
{
for(int i = n ; i!=1 ; i=pre[i]){
int u = pre[i];
flow[u][i] += d;
flow[i][u] -= d;
}
}

int main()
{
//freopen("a.in","rb",stdin);
int u,v,d;
while(scanf("%d%d" , &m , &n) == 2){
memset(cap , 0 ,sizeof(cap));
memset(flow , 0 ,sizeof(flow));
for(int i=0 ; i<m ; i++){
scanf("%d%d%d" , &u , &v , &d);
cap[u][v] += d; //可能有重边不断叠加
}

int ans = 0;
while(find_levelnet()){
int min_flow = get_min_flow();
ans += min_flow;
update(min_flow);
}

printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: