标签:
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 }
ACdream 1017 Fast Transportation
标签:
原文地址:http://www.cnblogs.com/qzqzgfy/p/5618476.html