【BZOJ】【2502】清理雪道

网络流/上下界网络流


  带下界的最小可行流……

  我SB了,跑网络流的时候是得从虚拟源0往出跑……而不是S……

  Orz Hzwer

  1 /**************************************************************
  2     Problem: 2502
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:3080 ms
  7     Memory:10652 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 2502
 11 #include<vector>
 12 #include<cstdio>
 13 #include<cstdlib>
 14 #include<cstring>
 15 #include<iostream>
 16 #include<algorithm>
 17 #define rep(i,n) for(int i=0;i<n;++i)
 18 #define F(i,j,n) for(int i=j;i<=n;++i)
 19 #define D(i,j,n) for(int i=j;i>=n;--i)
 20 using namespace std;
 21 int getint(){
 22     int v=0,sign=1; char ch=getchar();
 23     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
 24     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
 25     return v*sign;
 26 }
 27 typedef long long LL;
 28 const int N=100010,M=500010,INF=~0u>>2;
 29 /*******************tamplate********************/
 30 int n,m,ans;
 31 struct edge{int to,v;};
 32 struct Net{
 33     edge E[M];
 34     int head[N],next[M],cnt;
 35     void ins(int x,int y,int z){
 36         E[++cnt]=(edge){y,z};
 37         next[cnt]=head[x]; head[x]=cnt;
 38     }
 39     void add(int x,int y,int z){
 40         ins(x,y,z); ins(y,x,0);
 41     }
 42     int S,T,d[N],cur[N],Q[M];
 43     bool mklevel(){
 44         int l=0,r=-1;
 45         F(i,0,T) d[i]=-1;
 46         d[0]=0; Q[++r]=0;
 47         while(l<=r){
 48             int x=Q[l++];
 49             for(int i=head[x];i;i=next[i])
 50                 if(E[i].v && d[E[i].to]==-1){
 51                     d[E[i].to]=d[x]+1;
 52                     Q[++r]=E[i].to;
 53                 }
 54         }
 55         return d[T]!=-1;
 56     }
 57     int dfs(int x,int a){
 58         if (x==T) return a;
 59         int flow=0;
 60         for(int &i=cur[x];i && flow<a;i=next[i])
 61             if (E[i].v && d[E[i].to]==d[x]+1){
 62                 int f=dfs(E[i].to,min(E[i].v,a-flow));
 63                 E[i].v-=f;
 64                 E[i^1].v+=f;
 65                 flow+=f;
 66             }
 67         if (!flow) d[x]=-1;
 68         return flow;
 69     }
 70     void Dinic(){
 71         while(mklevel()){
 72             F(i,0,T) cur[i]=head[i];
 73             ans+=dfs(0,INF);
 74         }
 75     }
 76     int in[N];
 77     void init(){
 78         n=getint(); cnt=1; m=0;
 79         F(i,1,n){
 80             int x=getint(),y;
 81             F(j,1,x){
 82                 y=getint(); m++;
 83                 add(i,n+2*m-1,INF);
 84                 add(n+2*m,y,INF);
 85             }
 86         }
 87         S=n+m+m+1; T=S+1; ans=0;
 88         F(i,1,m){
 89             add(n+2*i-1,n+2*i,INF);
 90             in[n+2*i-1]--; in[n+2*i]++;
 91         }
 92         F(i,1,n) add(S,i,INF);
 93         F(i,n+1,n+m+m)
 94             if(in[i]>0) add(0,i,in[i]);
 95             else add(i,T,-in[i]);
 96         for(int i=1;;i++){
 97             add(0,S,1);
 98             Dinic();
 99             if (ans==m){printf("%d\n",i);break;}
100         }
101     }
102 }G1;
103 int main(){
104     #ifndef ONLINE_JUDGE
105     freopen("input.txt","r",stdin);
106 //  freopen("output.txt","w",stdout);
107     #endif
108     G1.init();
109     return 0;
110 }
View Code

 

2502: 清理雪道

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 182  Solved: 96
[Submit][Status][Discuss]

Description

       滑雪场坐落在FJ省西北部的若干座山上。
从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向。
你的团队负责每周定时清理雪道。你们拥有一架直升飞机,每次飞行可以从总部带一个人降落到滑雪场的某个地点,然后再飞回总部。从降落的地点出发,这个人可以顺着斜坡向下滑行,并清理他所经过的雪道。
由于每次飞行的耗费是固定的,为了最小化耗费,你想知道如何用最少的飞行次数才能完成清理雪道的任务。
 

Input

输入文件的第一行包含一个整数n (2 <= n <= 100) – 代表滑雪场的地点的数量。接下来的n行,描述1~n号地点出发的斜坡,第i行的第一个数为mi (0 <= mi < n) ,后面共有mi个整数,由空格隔开,每个整数aij互不相同,代表从地点i下降到地点aij的斜坡。每个地点至少有一个斜坡与之相连。

Output

 
       输出文件的第一行是一个整数k直升飞机的最少飞行次数。
 

Sample Input

8
1 3
1 7
2 4 5
1 8
1 8
0
2 6 5
0

Sample Output

4

HINT

Source

[Submit][Status][Discuss]
posted @ 2015-04-04 21:21  Tunix  阅读(263)  评论(0编辑  收藏  举报