【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

 

 
posted @ 2014-12-09 17:27  iwtwiioi  阅读(402)  评论(0编辑  收藏  举报