首页 > 代码库 > 【BZOJ】2929: [Poi1999]洞穴攀行(最大流)

【BZOJ】2929: [Poi1999]洞穴攀行(最大流)

http://www.lydsy.com/JudgeOnline/problem.php?id=2929

题意描述不清。。搞得我wa了一发。。

应该是,有1和n的点的边容量都为1,其余随便。。。

然后是裸题。。

#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <iostream>#include <algorithm>#include <queue>#include <set>#include <map>using namespace std;typedef long long ll;#define rep(i, n) for(int i=0; i<(n); ++i)#define for1(i,a,n) for(int i=(a);i<=(n);++i)#define for2(i,a,n) for(int i=(a);i<(n);++i)#define for3(i,a,n) for(int i=(a);i>=(n);--i)#define for4(i,a,n) for(int i=(a);i>(n);--i)#define CC(i,a) memset(i,a,sizeof(i))#define read(a) a=getint()#define print(a) printf("%d", a)#define dbg(x) cout << (#x) << " = " << (x) << endl#define error(x) (!(x)?puts("error"):0)#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<‘0‘||c>‘9‘; c=getchar()) if(c==‘-‘) k=-1; for(; c>=‘0‘&&c<=‘9‘; c=getchar()) r=r*10+c-‘0‘; return k*r; }const int N=415, oo=~0u>>1;int ihead[N], cnt=1;struct dat { int next, to, from, cap; }e[N*N*2];void add(int u, int v, int c) {	e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].from=u; e[cnt].to=v; e[cnt].cap=c;	e[++cnt].next=ihead[v]; ihead[v]=cnt; e[cnt].from=v; e[cnt].to=u; e[cnt].cap=0;}int p[N], d[N], gap[N], cur[N];int isap(int s, int t, int n) {	for1(i, 0, n) p[i]=0, d[i]=0, gap[i]=0, cur[i]=ihead[i];	gap[0]=n; int ret=0, f, u=s, i;	while(d[s]<n) {		for(i=cur[u]; i; i=e[i].next) if(e[i].cap && d[e[i].to]+1==d[u]) break;		if(i) {			p[e[i].to]=cur[u]=i; u=e[i].to;			if(u==t) {				for(f=oo; u!=s; u=e[p[u]].from) f=min(f, e[p[u]].cap);				for(u=t; u!=s; u=e[p[u]].from) e[p[u]].cap-=f, e[p[u]^1].cap+=f;				ret+=f;			}		}		else {			if(!(--gap[d[u]])) break;			d[u]=n; cur[u]=ihead[u];			for(i=ihead[u]; i; i=e[i].next) if(e[i].cap && d[e[i].to]+1<d[u]) d[u]=d[e[i].to]+1;			++gap[d[u]];			if(u!=s) u=e[p[u]].from;		}	}	return ret;}int n;int main() {	read(n);	for1(i, 1, n-1) {		int k=getint();		while(k--) {			int t=getint();			if(i==1 || t==n) add(i, t, 1);			else add(i, t, oo);		}	}	printf("%d\n", isap(1, n, n));	return 0;}

  

 


 

 

Description

一队洞穴学者在Byte Mountain的Grate Cave里组织了一次训练。训练中,每一位洞穴学者要从最高的一个室到达最底下的一个室。他们只能向下走。一条路上每一个连续的室都要比它的前一个低。此外,每一个洞穴学者都要从最高的室出发,沿不同的路走到最低的室。问:可以有多少个人同时参加训练?
 
任务:
写一个程序:
l        读入对洞穴的描述。
l         计算可以同时参加训练的人数。
l         将结果输出。
 

Input

 
第一行有一个整数n(2<=n<=200),等于洞穴中室的个数。用1~n给室标号,号码越大就在越下面。最高的室记为1,最低的室记为n。以下的n-1行是对通道的描述。第I+1行包含了与第I个室有通道的室(只有比标号比I大的室)。这一行中的第一个数是m,0<=m<=(n-i+1),表示被描述的通道的个数。接着的m个数字是与第I个室有通道的室的编号。
 

Output

 
输出一个整数。它等于可以同时参加训练的洞穴学者的最大人数。
 

Sample Input

12
4 3 4 2 5
1 8
2 9 7
2 6 11
1 8
2 9 10
2 10 11
1 12
2 10 12
1 12
1 12

Sample Output

3

HINT

 

Source

 

 

【BZOJ】2929: [Poi1999]洞穴攀行(最大流)