码迷,mamicode.com
首页 > 其他好文 > 详细

【POJ 3204】Ikki's Story I - Road Reconstruction

时间:2015-03-13 16:39:30      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:bzoj   oi   网络流   

Ikki‘s Story I - Road Reconstruction
Time Limit: 2000MS   Memory Limit: 131072K
Total Submissions: 7089   Accepted: 2039

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 NM (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 abc, which means that there is a road from city a to city b with a transportation capacity of c (0 ≤ ab < nc ≤ 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 numbered n ? 1.

Output

You should output one line consisting of only one integer K, 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


网络流。


如果增加一条边的流量能增加总流量,说明是这条边一定是满流的,因为他的限制导致了最大流不能再大。

(其实相当于求最小割的必须边)


准确来说这条边满足两个性质:

1.满流


2.从s能到达这条边的from,从这条边的to能到达t


求最大流+两次dfs即可。



#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#define M 500+5
#define inf 0x3f3f3f3f
using namespace std;
int tot=1,h[M],vs[M],vt[M],v[M],d[M],cur[M],n,m;
struct edge
{
	int from,to,cap,flow,ne;
}E[200005];
void Addedge(int from,int to,int cap)
{
	E[++tot]=(edge){from,to,cap,0,h[from]};
	h[from]=tot;
	E[++tot]=(edge){to,from,0,0,h[to]};
	h[to]=tot;
}
bool bfs()
{
	queue<int> q;
	for (int i=0;i<n;i++)
		v[i]=0;
	v[0]=1;
	d[0]=0;
	q.push(0);
	while (!q.empty())
	{
		int x=q.front();
		q.pop();
		for (int i=h[x];i;i=E[i].ne)
		{
			edge e=E[i];
			if (!v[e.to]&&e.cap>e.flow)
			{
				v[e.to]=1;
				d[e.to]=d[x]+1;
				q.push(e.to);
			}
		}
	}
	return v[n-1];
}
int dfs(int x,int a)
{
	if (x==n-1||!a) return a;
	int flow=0;
	for (int &i=cur[x];i;i=E[i].ne)
	{
		edge &e=E[i];
		if (d[e.to]!=d[x]+1) continue;
		int f=dfs(e.to,min(a,e.cap-e.flow));
		if (f)
		{
			a-=f;
			e.flow+=f;
			E[i^1].flow-=f;
			flow+=f;
			if (!a) break;
		}
	}
	return flow;
}
void dinic()
{
	int flow=0;
	while (bfs())
	{
		for (int i=0;i<n;i++)
			cur[i]=h[i];
		flow+=dfs(0,inf);
	}
}
void dfs_s(int x)
{
	for (int i=h[x];i;i=E[i].ne)
	{
		if (i&1) continue;
		edge e=E[i];
		if (e.cap>e.flow&&!vs[e.to])
		{
			vs[e.to]=1;
			dfs_s(e.to);
		}
	}
}
void dfs_t(int x)
{
	for (int i=h[x];i;i=E[i].ne)
	{
		if ((i&1)==0) continue;
		edge e=E[i^1];
		if (e.cap>e.flow&&!vt[e.from])
		{
			vt[e.from]=1;
			dfs_t(e.from);
		}
	}
}
int main()
{
    scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
	{
		int x,y,c;
		scanf("%d%d%d",&x,&y,&c);
		Addedge(x,y,c);
	}
	dinic();
	vs[0]=1,vt[n-1]=1;
	dfs_s(0);
	dfs_t(n-1);
	int cnt=0;
	for (int i=2;i<=tot;i+=2)
		if (E[i].flow==E[i].cap&&vs[E[i].from]&&vt[E[i].to])
			cnt++;
	printf("%d\n",cnt);
	return 0;
}

技术分享


感悟:

1.RE是dfs_s和dfs_t写混了

【POJ 3204】Ikki's Story I - Road Reconstruction

标签:bzoj   oi   网络流   

原文地址:http://blog.csdn.net/regina8023/article/details/44241685

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!