2929: [Poi1999]洞穴攀行
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 499 Solved: 295
[Submit][Status][Discuss]
Description
洞穴学者在Byte Mountain的Grate Cave里组织了一次训练。训练中,每一位洞穴学者要从最高的一个室到达最底下的一个室。他们只能向下走。一条路上每一个连续的室都要比它的前一个低。此外,每一个洞穴学者都要从最高的室出发,沿不同的路走到最低的室。
限制:
1.起点连接的通道同一时间只能容纳一个人通过
2.终点连接的通道同一时间只能容纳一个人通过
3.其他边都很宽敞,同一时间可以容纳无限多的人
问:可以有多少个人同时参加训练?
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
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
裸网络流
题意,1出发以及到达n的边只能走一次
1 #include<cstring> 2 #include<cmath> 3 #include<cstdio> 4 #include<algorithm> 5 #include<iostream> 6 #include<queue> 7 8 #define N 207 9 #define M 100007 10 #define inf 1000000007 11 12 #define Wb putchar(' ') 13 #define We putchar(' ') 14 #define rg register int 15 using namespace std; 16 inline int read() 17 { 18 int x=0,f=1;char ch=getchar(); 19 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 20 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 21 return x*f; 22 } 23 inline void write(int x) 24 { 25 if(x<0) putchar('-'),x=-x; 26 if (x==0) putchar(48); 27 int num=0;char c[15]; 28 while(x) c[++num]=(x%10)+48,x/=10; 29 while(num) putchar(c[num--]); 30 } 31 32 int n,S,T; 33 int cnt=1,hed[N],nxt[M],rea[M],val[M],cur[N]; 34 int dis[N]; 35 bool flag[N]; 36 37 void add(int u,int v,int w) 38 { 39 nxt[++cnt]=hed[u]; 40 hed[u]=cnt; 41 rea[cnt]=v; 42 val[cnt]=w; 43 } 44 void add_two_way(int u,int v,int w) 45 { 46 add(u,v,w), 47 add(v,u,0); 48 } 49 bool bfs() 50 { 51 for (int i=S;i<=T;i++)dis[i]=-1; 52 dis[S]=0;queue<int>q;q.push(S); 53 while(!q.empty()) 54 { 55 int u=q.front();q.pop(); 56 for (int i=hed[u];i!=-1;i=nxt[i]) 57 { 58 int v=rea[i],fee=val[i]; 59 if (dis[v]!=-1||fee==0)continue; 60 dis[v]=dis[u]+1; 61 if (v==T)return 1; 62 q.push(v); 63 } 64 } 65 return 0; 66 } 67 int dfs(int u,int MX) 68 { 69 if (u==T||MX==0) return MX; 70 int res=0; 71 for (int i=cur[u];i!=-1;i=nxt[i]) 72 { 73 int v=rea[i],fee=val[i]; 74 if (dis[v]!=dis[u]+1)continue; 75 int x=dfs(v,min(MX,fee)); 76 cur[u]=i,res+=x,MX-=x; 77 val[i]-=x,val[i^1]+=x; 78 if (!MX)break; 79 } 80 if (!res) dis[u]=-1; 81 return res; 82 } 83 int dinic() 84 { 85 int res=0; 86 while(bfs()) 87 { 88 for (int i=S;i<=T;i++)cur[i]=hed[i]; 89 res+=dfs(S,inf); 90 } 91 return res; 92 } 93 94 int main() 95 { 96 n=read();memset(hed,-1,sizeof(hed)); 97 S=1,T=n; 98 for (rg i=1;i<n;i++) 99 { 100 int num=read(); 101 for (int j=1;j<=num;j++) 102 { 103 int x=read(); 104 if (i==1||x==T) add_two_way(i,x,1); 105 else add_two_way(i,x,inf); 106 } 107 } 108 write(dinic()); 109 }