【网络流24题】星际转移(分层图+枚举)
来源:互联网 发布:php compact 编辑:程序博客网 时间:2024/06/05 11:33
传送门
星际转移
题意:给出若干容纳人数不同的太空船循环停站路线(特定时间停特定站),任意两站之间行驶耗时为1,求k个人从起点地球到终点月球的最小耗时.
I think
分层图问题.对每个太空站i在第day天建立点< i,day>,相当于在枚举day时通过添加新边和新点将图层层展开.
乘客可以在某个站点等待,因此需要增设< i,day-1> —> < i,day>容量为Inf的边.
乘客可以坐车从站i到站j,因此需增设< i,day-1> —> < j,day>容量为车载量的边.
当最大流==总人数k时day即答案.
什么时候用分层图来解题? 从我的理解看,应当是在尝试用边的容量和费用设限然而仍然无法建出得到答案的图时,考虑用分层图枚举/二分答案.
Code
#include<cstdio>#include<cstring>#include<queue>using namespace std;const int sm = 20*50+10;const int sn = 1e6+10;const int Inf = 0x3f3f3f3f;int N,M,K,S,T,tot=1,Flw,d;int to[sn],hd[sm],nxt[sn],_c[sn],c[sn];int h[50],r[50],p[50][50],fa[50];int lev[sm],cur[sm];int Find(int x) { if(x!=fa[x]) return fa[x]=Find(fa[x]); return fa[x];}int Min(int x,int y) { return x<y?x:y; }void Add(int u,int v,int w) { to[++tot]=v,nxt[tot]=hd[u],hd[u]=tot,_c[tot]=c[tot]=w; to[++tot]=u,nxt[tot]=hd[v],hd[v]=tot,_c[tot]=c[tot]=0;}bool Bfs(int sum) { for(int i=0;i<=sum;++i) lev[i]=0; lev[T]=0; queue<int>q; int t; q.push(S),lev[S]=1; while(!q.empty()) { t=q.front(),q.pop(); for(int i=hd[t];i;i=nxt[i]) if(c[i]>0&&!lev[to[i]]) { lev[to[i]]=lev[t]+1; if(to[i]==T) return 1; q.push(to[i]); } } return lev[T];}int Dfs(int x,int mx) { if(x==T||!mx) return mx; int f; for(int i=cur[x]?cur[x]:hd[x];i;i=nxt[i]) { cur[x]=i; if(c[i]>0&&lev[to[i]]==lev[x]+1) if(f=Dfs(to[i],Min(mx,c[i]))) return c[i]-=f,c[i^1]+=f,f; } return 0;}void Dinic(int sum) { int f; Flw=0; while(Bfs(sum)) { for(int i=0;i<=sum;++i) cur[i]=0; cur[T]=0; while(f=Dfs(S,Inf)) Flw+=f; }}int Point(int x,int d) { return d*N+x;}int main() { int u; scanf("%d%d%d",&N,&M,&K); for(int i=1;i<=N+2;++i) fa[i]=i; for(int i=1;i<=M;++i) { scanf("%d%d",&h[i],&r[i]); for(int j=1,v;j<=r[i];++j) { scanf("%d",&p[i][j]); if(!p[i][j]) p[i][j]=N+1; if(p[i][j]==-1) p[i][j]=N+2; u=Find(p[i][j]); if(j==1) v=u; else fa[u]=v; } } if(Find(N+1)!=Find(N+2)) puts("0"); else { N+=2,S=0,T=sm-1; int q,fm,tt; Add(S,Point(N-1,0),Inf); Add(Point(N,0),T,Inf); do { ++d; if(d>1) for(int i=2;i<=tot;++i) c[i]=_c[i]; Add(S,Point(N-1,d),Inf); Add(Point(N,d),T,Inf); for(int i=1;i<=N;++i) Add(Point(i,d-1),Point(i,d),Inf); for(int i=1;i<=M;++i) { tt=d%r[i]+1; fm=(tt==1)?r[i]:tt-1; Add(Point(p[i][fm],d-1),Point(p[i][tt],d),h[i]); } Dinic((d+1)*N); }while(Flw<K); printf("%d\n",d); } return 0;} 子任务 #1
阅读全文
0 0
- 【网络流24题】星际转移(分层图+枚举)
- loj6015「网络流 24 题」星际转移(枚举+分层图最大流)
- 网络流24题之十三 星际转移 分层图网络流
- 十三、星际转移问题 [分层图网络流问题]
- nefu483星际转移问题(分层图网络流)
- 十三、星际转移问题 [分层图网络流问题]
- 【网络流24题】星际转移问题
- [网络流24题]星际转移问题
- [网络流 24 题] 星际转移问题
- 星际转移问题[网络流24题之13]
- 网络流24题13. 星际转移问题
- BZOJ 736 [CTSC1999][网络流24题] 星际转移
- 「网络流 24 题」星际转移
- 【网络流】星际转移问题
- 线性规划与网络流24——星际转移问题
- 网络流二十四题之十 —— 星际转移问题(HOME)
- 【codevs1034】星际转移问题(家园)(网络流)
- HDU 1733 [Escape] 分层图网络流+枚举时间
- Qt网络编程--HTTP服务器(五)
- P1583 魔法照片
- 搜狐[编程题] 袋鼠过河.一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子,每隔一米就有一个
- 4-1 求奇数和
- java学习_常用API
- 【网络流24题】星际转移(分层图+枚举)
- c++入门教程(十五)
- 异常处理,abort(),exit(),返回错误码
- tf.segment_sum和tf.unsorted_segment_sum实例
- 信息标记与提取方法
- 【拜小白opencv】24-半阈值化操作
- 4-2 展开式求和
- Mina入门-二
- 复习java