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

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

POJ Monthly--2007.03.04, Ikki

网络流。

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

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

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

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

时间: 2024-11-08 22:02:59

【POJ 3204】Ikki's Story I - Road Reconstruction的相关文章

poj 3204 Ikki&#39;s Story I - Road Reconstruction

Ikki's Story I - Road Reconstruction 题意:有N个顶点和M条边N, M (N ≤ 500, M ≤ 5,000)  ,试图改变图中的一条边使得从0到N-1的流量增加:问这样的边有几条? 思路:刚最大流入门,之后一看就觉得满流的边就是答案..真是太天真了.之后看了题解,发现满流只是前提(即使满流是几次残量的叠加也是一样),还有一个条件是,该路径的最大流量只受该边影响:即可以从S和T遍历到该边的两个端点,这就是为什么之后还要dfs给点涂色的原因:涂色前要对残余网络

【POJ 1408】 Fishnet (叉积求面积)

[POJ 1408] Fishnet (叉积求面积) 一个1*1㎡的池塘 有2*n条线代表渔网 问这些网中围出来的最大面积 一个有效面积是相邻两行和相邻两列中间夹的四边形 Input为n 后面跟着四行 每行n个浮点数 每一行分别代表a,b,c,d 如图 并且保证a(i) > a(i-1) b(i) > b(i-1) c(i) > c(i-1) d(i) > d(i-1) n(n <= 30)*2+4(四个岸)条边 枚举点数就行 相邻的四个四个点枚举 找出围出的最大面积 找点用

【POJ 2513】Colored Sticks

[POJ 2513]Colored Sticks 并查集+字典树+欧拉通路 第一次做这么混的题..太混了-- 不过题不算难 字典树用来查字符串对应图中的点 每个单词做一个点(包括重复单词 题意就是每个边走且直走一次(欧拉通路 欧拉图的判定: 没有或者只有两个奇数度的点的图叫做欧拉图 有这些就可以解答此题了 另外需要注意题目范围是25W个木棍 所以最多可能有50W个点 卡了好多个RE 代码如下: #include <iostream> #include <cstdlib> #incl

2292: 【POJ Challenge 】永远挑战

2292: [POJ Challenge ]永远挑战 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 553  Solved: 230[Submit][Status][Discuss] Description lqp18_31和1tthinking经常出题来虐ftiasch.有一天, lqp18_31搞了一个有向图,每条边的长度都是1. 他想让ftiasch求出点1到点 N 的最短路."水题啊.", ftiasch这么说道. 所以1tth

【POJ 1201】 Intervals(差分约束系统)

[POJ 1201] Intervals(差分约束系统) 11 1716的升级版 把原本固定的边权改为不固定. Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23817   Accepted: 9023 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a p

【POJ 1228】Grandpa&#39;s Estate 凸包

找到凸包后暴力枚举边进行$check$,注意凸包是一条线(或者说两条线)的情况要输出$NO$ #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define N 1003 #define read(x) x = getint() using namespace std; inline int getint() { int k = 0, fh = 1; char c

POJ 3204 Ikki&#39;s Story I - Road Reconstruction(最大流)

POJ 3204 Ikki's Story I - Road Reconstruction 题目链接 题意:给定一个有向图,求出最大流后,问哪些边增加容量后,可以使最大流增加 思路:对于一个可以增加的,必然原来就是满流,并且从源点到汇点,的一条路径上,都是还有残留容量的,这样只要从源点和汇点分别出发dfs一遍,标记掉经过点,然后枚举满流边,如果两端都是标记过的点,这个边就是可以增加的 代码: #include <cstdio> #include <cstring> #include

【POJ 2750】 Potted Flower(线段树套dp)

[POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4566   Accepted: 1739 Description The little cat takes over the management of a new park. There is a large circular statue in the center of the park, surrou

【POJ 2480】Longge&#39;s problem(欧拉函数)

题意 求$ \sum_{i=1}^n gcd(i,n) $ 给定 $n(1\le n\le 2^{32}) $. 链接 分析 用欧拉函数$φ(x)$求1到x-1有几个和x互质的数. gcd(i,n)必定是n的一个约数.若p是n的约数,那么gcd(i,n)==p的有$φ(n/p)$个数,因为要使gcd(i,n)==p,i/p和n/p必须是互质的.那么就是求i/p和n/p互质的i在[1,n]里有几个,就等价于,1/p,2/p,...,n/p里面有几个和n/p互质,即φ(n/p). 求和的话,约数为p