[cogs736][网络流24题#13]星际转移[网络流,网络判定]

将一个空间站分为天数个点,每次枚举天数,每增加一天就把对应天数的边连上,用网络流判定可行性,即-判断最大流是否不小于k,注意编号不要错位。通过此题,可见一些网络流题目需要用到网络判定方法,但虽然答案具有单调性,却不适合二份答案,原因有两个:一是网络流题目一般数据规模不会很大,二是网络流题目如果二分就必须每次全部重新建图,而普通枚举可以在上以阶段的图中递推操作,所以往往枚举的效率和代码复杂度更好。

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <cmath>
  7 #include <ctime>
  8 #include <queue>
  9 
 10 using namespace std;
 11 
 12 #define    INF    0x3f3f3f3f
 13 
 14 template<const int _n>
 15 struct Edge
 16 {
 17     struct Edge_base { int    to,w,next; }e[_n];
 18     int    cnt,p[_n];
 19     Edge() { clear(); }
 20     void    clear() { cnt=1,memset(p,0,sizeof(p)); }
 21     int    start(const int x) { return p[x]; }
 22     Edge_base&    operator[](const int x) { return e[x]; }
 23     void    insert(const int x,const int y,const int z)
 24     { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; p[x]=cnt; return ; }
 25 };
 26 
 27 int    n,m,SSS,TTT,Flow;
 28 int    level[5100],cur[5100],h[5100];
 29 vector<int>    vec[5100];
 30 Edge<210000>    e;
 31 
 32 bool    Bfs(const int S)
 33 {
 34     int    i,t;
 35     queue<int>    Q;
 36     memset(level,0,sizeof(level));
 37     level[S]=1;
 38     Q.push(S);
 39     while(!Q.empty())
 40     {
 41         t=Q.front(),Q.pop();
 42         for(i=e.start(t);i;i=e[i].next)
 43         {
 44             if(!level[e[i].to] && e[i].w)
 45             {
 46                 level[e[i].to]=level[t]+1;
 47                 Q.push(e[i].to);
 48             }
 49         }
 50     }
 51     return level[TTT];
 52 }
 53 
 54 int    Dfs(const int S,const int bk)
 55 {
 56     if(S==TTT)return bk;
 57     int    rest=bk;
 58     for(int &i=cur[S];i;i=e[i].next)
 59     {
 60         if(level[e[i].to]==level[S]+1 && e[i].w)
 61         {
 62             int    flow=Dfs(e[i].to,min(rest,e[i].w));
 63             e[i].w-=flow;
 64             e[i^1].w+=flow;
 65             if((rest-=flow)<=0)break;
 66         }
 67     }
 68     if(rest==bk)level[S]=0;
 69     return bk-rest;
 70 }
 71 
 72 int    Dinic()
 73 {
 74     while(Bfs(SSS))
 75     {
 76         memcpy(cur,e.p,sizeof(cur));
 77         Flow+=Dfs(SSS,0x3f3f3f3f);
 78     }
 79     return Flow;
 80 }
 81 
 82 int    P(const int x,const int y)
 83 {
 84     return y*n+x;
 85 }
 86 
 87 int main()
 88 {
 89     freopen("home.in","r",stdin);
 90     freopen("home.out","w",stdout);
 91     int    i,j,t,k,c;
 92 
 93     scanf("%d%d%d",&n,&m,&k);
 94     for(i=1;i<=m;++i)
 95     {
 96         scanf("%d%d",&h[i],&t);
 97         for(j=1;j<=t;++j)
 98         {
 99             scanf("%d",&c);
100             if(c==-1)c=n+1;if(c==0)c=n+2;
101             vec[i].push_back(c);
102             if(j!=1)e.insert(vec[i][j-2],vec[i][j-1],1);
103         }
104         e.insert(vec[i][t-1],vec[i][0],i);
105     }
106     
107     SSS=n+2,TTT=n+1;
108     n+=2;
109     int    S=n,T=n-1;
110     if(!Bfs(SSS)){printf("0\n");goto End;}
111 
112     e.clear();SSS=1000,TTT=SSS+1;
113     e.insert(SSS,P(S,0),INF);e.insert(P(S,0),SSS,0);
114     e.insert(P(T,0),TTT,INF);e.insert(TTT,P(T,0),0);
115     for(i=1;;i++)
116     {
117         e.insert(SSS,P(S,i),INF);
118         e.insert(P(S,i),SSS,0);
119         e.insert(P(T,i),TTT,INF);
120         e.insert(TTT,P(T,i),0);
121         for(j=1;j<=n;++j)
122         {
123             e.insert(P(j,i-1),P(j,i),INF);
124             e.insert(P(j,i),P(j,i-1),0);
125         }
126         for(j=1;j<=m;++j)
127         {
128             e.insert(P(vec[j][(i-1)%vec[j].size()],i-1),P(vec[j][i%vec[j].size()],i),h[j]);
129             e.insert(P(vec[j][i%vec[j].size()],i),P(vec[j][(i-1)%vec[j].size()],i-1),0);
130         }
131         if(Dinic()>=k)break;
132     }    
133 
134     printf("%d\n",i);
135 
136 End:
137     return 0;
138 }

 

posted @ 2015-12-31 02:12  Gster  阅读(170)  评论(0编辑  收藏  举报