ACdream 1017 Fast Transportation

http://acdream.info/problem?pid=1017

题意:给n个点,m条边,K个货物,要从从S到T,每天每条边最多只能经过1次,求要几天能运完

思路:拆成分层图,每层向下一层连边,注意i也能连到i,流量为inf,代表这个点的货车这天没动

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #define inf 0x7fffffff
 7 struct edge{
 8     int u,v;
 9 }e[200005];
10 int tot,go[500005],next[500005],first[500005],op[500005],flow[500005],dis[500005],cnt[500005];
11 int T,S,ss,tt,n,m,nodes,K;
12 int id[105][105];
13 int read(){
14     int t=0,f=1;char ch=getchar();
15     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
16     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
17     return t*f;
18 }
19 void insert(int x,int y,int z){
20     tot++;
21     go[tot]=y;
22     next[tot]=first[x];
23     first[x]=tot;
24     flow[tot]=z;
25 }
26 void add(int x,int y,int z){
27     insert(x,y,z);op[tot]=tot+1;
28     insert(y,x,0);op[tot]=tot-1;
29 }
30 int dfs(int x,int f){
31     if (x==T) return f;
32     int mn=nodes,sum=0;
33     for (int i=first[x];i;i=next[i]){
34          int pur=go[i];
35          if (flow[i]&&dis[pur]+1==dis[x]){
36              int save=dfs(pur,std::min(flow[i],f-sum));
37              flow[i]-=save;
38              flow[op[i]]+=save;
39              sum+=save;
40              if (dis[S]>=nodes||f==sum) return sum;
41          }
42          if (flow[i]) mn=std::min(mn,dis[pur]);
43     }
44     if (sum==0){
45         cnt[dis[x]]--;
46         if (cnt[dis[x]]==0){
47            dis[S]=nodes;
48         }else{
49            dis[x]=mn+1;
50            cnt[dis[x]]++;
51         }
52     }
53     return sum;
54 }
55 bool check(int mid){
56     for (int i=0;i<=nodes;i++) first[i]=cnt[i]=dis[i]=0;tot=0;
57     int sz=0;
58     for (int i=1;i<=mid;i++)
59         for (int j=1;j<=n;j++)
60             id[i][j]=++sz;
61     T=sz+1;
62     sz+=2;
63     S=0;nodes=sz;
64     add(S,id[1][ss],K);
65     for (int i=1;i<=mid;i++)
66         add(id[i][tt],T,K);
67     for (int i=1;i<mid;i++)
68      for (int j=1;j<=n;j++)
69       add(id[i][j],id[i+1][j],inf);    
70     for (int i=1;i<=m;i++)
71         for (int j=1;j<mid;j++)
72             add(id[j][e[i].u],id[j+1][e[i].v],1),add(id[j][e[i].v],id[j+1][e[i].u],1);
73     int Ans=0;
74     while (dis[S]<nodes) Ans+=dfs(S,inf);
75     return Ans==K;    
76 }
77 int main(){
78     while (scanf("%d",&n)!=EOF){
79          m=read();K=read();ss=read();tt=read();
80          for (int i=1;i<=m;i++)
81             e[i].u=read(),e[i].v=read();
82          int l=1,r=n+K+2,ans=0;
83          while (l<=r){
84             int mid=(l+r)/2;
85             if (check(mid)) r=mid-1,ans=mid;
86                 else l=mid+1;
87           }
88           printf("%d\n",ans-1);
89     }
90 }

 

posted @ 2016-06-26 20:08  GFY  阅读(166)  评论(0编辑  收藏  举报