首页 > 其他 > 详细

POJ 3204 最小割边

时间:2014-03-09 18:45:15      阅读:597      评论:0      收藏:0      [点我收藏+]
Ikki‘s Story I - Road Reconstruction
Time Limit: 2000MS   Memory Limit: 131072K
Total Submissions: 6537   Accepted: 1866

Description

Ikki is the king of a small country – Phoenix, Phoenix is so small that there is only one city that is responsible for the production of daily goods, and uses the road network to transport the goods to the capital. Ikki finds that the biggest problem in the country is that transportation speed is too slow.

Since Ikki was an ACM/ICPC contestant before, he realized that this, indeed, is a maximum flow problem. He coded a maximum flow program and found the answer. Not satisfied with the current status of the transportation speed, he wants to increase the transportation ability of the nation. The method is relatively simple, Ikki will reconstruct some roads in this transportation network, to make those roads afford higher capacity in transportation. But unfortunately, the country of Phoenix is not so rich in GDP that there is only enough money to rebuild one road. Ikki wants to find such roads that if reconstructed, the total capacity of transportation will increase.

He thought this problem for a loooong time but cannot get it. So he gave this problem to frkstyc, who put it in this POJ Monthly contest for you to solve. Can you solve it for Ikki?

Input

The input contains exactly one test case.

The first line of the test case contains two integers N, M (N ≤ 500,M ≤ 5,000) which represents the number of cities and roads in the country, Phoenix, respectively.

M lines follow, each line contains three integers a, b,c, which means that there is a road from city a to city b with a transportation capacity ofc (0 ≤ a, b < n, c ≤ 100). All the roads are directed.

Cities are numbered from 0 to n ? 1, the city which can product goods is numbered 0, and the capital is numberedn ? 1.

Output

You should output one line consisting of only one integerK, denoting that there are K roads, reconstructing each of which will increase the network transportation capacity.

Sample Input

2 1
0 1 1

Sample Output

1

Source


给定一个图,求有多少边增大流量可以使得从源点到汇点流量增大,先求最大流,然后找割边,残余流量为0的边不一定是,从源点沿着流量不为0的边搜,

从汇点沿着流量不为0的边反向搜索,正向标记为1,反向标记为2,当且仅当一条边起点为1,终点为2时,符合题目要求,

sap模板有问题,wa一片,幸亏发现得早。

代码:

/* ***********************************************
Author :rabbit
Created Time :2014/3/9 13:38:47
File Name :treap2.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
const int maxn=20100;
const int maxm=1002000;
struct Edge{
	int next,to,cap;
	Edge(){};
	Edge(int _next,int _to,int _cap){
		next=_next;to=_to;cap=_cap;
	}
}edge[maxm];
int head[maxn],tol,dep[maxn],gap[maxn];
void addedge(int u,int v,int flow){
    edge[tol]=Edge(head[u],v,flow);head[u]=tol++;
    edge[tol]=Edge(head[v],u,0);head[v]=tol++;
}
void bfs(int start,int end){
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    gap[0]++;int front=0,rear=0,Q[maxn];
    dep[end]=0;Q[rear++]=end;
    while(front!=rear){
        int u=Q[front++];
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;if(dep[v]==-1)
                Q[rear++]=v,dep[v]=dep[u]+1,gap[dep[v]]++;
        }
    }
}
int sap(int s,int t,int N){
	int res=0;bfs(s,t);
	int cur[maxn],S[maxn],top=0,u=s,i;
	memcpy(cur,head,sizeof(head));
	while(dep[s]<N){
		if(u==t){
			int temp=INF,id;
		    for( i=0;i<top;i++)
			   if(temp>edge[S[i]].cap)
				   temp=edge[S[i]].cap,id=i;
		    for( i=0;i<top;i++)
			      edge[S[i]].cap-=temp,edge[S[i]^1].cap+=temp;
		    res+=temp;top=id;u=edge[S[top]^1].to;
		}
		if(u!=t&&gap[dep[u]-1]==0)break;
		for( i=cur[u];i!=-1;i=edge[i].next)
			if(edge[i].cap&&dep[u]==dep[edge[i].to]+1)break;
		if(i!=-1)cur[u]=i,S[top++]=i,u=edge[i].to;
		else{
			int MIN=N;
			for( i=head[u];i!=-1;i=edge[i].next)
				if(edge[i].cap&&MIN>dep[edge[i].to])
					MIN=dep[edge[i].to],cur[u]=i;
			--gap[dep[u]];++gap[dep[u]=MIN+1];
			if(u!=s)u=edge[S[--top]^1].to;
		}
	}
	return res;
}
int mark[600];
void dfs1(int u){
	if(mark[u])return;
	mark[u]=1;
	for(int i=head[u];i!=-1;i=edge[i].next){
		int v=edge[i].to;
		if(!mark[v]&&edge[i].cap>0)dfs1(v);
	}
}
void dfs2(int u){
	if(mark[u])return;
	mark[u]=2;
	for(int i=head[u];i!=-1;i=edge[i].next){
		int v=edge[i].to;
		if(!mark[v]&&edge[i^1].cap>0)dfs2(v);
	}
}
int main(){
	int n,m;
	while(scanf("%d%d",&n,&m)==2){
		memset(head,-1,sizeof(head));tol=0;
		while(m--){
			int i,j,k;
			scanf("%d%d%d",&i,&j,&k);
			addedge(i,j,k);
		}
		int cnt=sap(0,n-1,3*n+100);
		//cout<<cnt<<endl;
		memset(mark,0,sizeof(mark));
		int ans=0;
		dfs1(0);dfs2(n-1);
		//for(int i=0;i<n;i++)cout<<mark[i]<<" ";cout<<endl;
		for(int i=0;i<tol;i+=2)
			if(mark[edge[i^1].to]==1&&mark[edge[i].to]==2&&edge[i].cap==0)ans++;
		cout<<ans<<endl;
	}
}


POJ 3204 最小割边,布布扣,bubuko.com

POJ 3204 最小割边

原文:http://blog.csdn.net/xianxingwuguan1/article/details/20846723

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!