家园 codevs1034 ctsc1999 最大流
2017-04-05 19:43
351 查看
题目描述 Description
由于人类对自然的疯狂破坏,人们意识到在大约2300年之后,地球不能再居住了,于是在月球上建立了新的绿地,以便在需要时移民。令人意想不到的是,2177年冬由于未知的原因,地球环境发生了连锁崩溃,人类必须在最短的时间内迁往月球。现有n个太空站处于地球与月球之间(编号1..n),m艘公共交通太空船在其中来回穿梭,每个太空站Si可容纳无限的人,每艘太空船pi只可容纳Hpi人。对于每一艘太空船pi,将周期性地停靠一系列的太空站(Si1,Si2…Sir),如:(1,3,4)表示停靠太空站1 3 4 1 3 4 1 3 4 …。 任一艘太空船从任一个太空站驶往另一个任意的太空站耗时为1。人只能在太空船停靠太空站(或地球、月球)时上船或下船。初始时的人全在地球上,太空船全在初始站(太空船pi处于Si1),目标是让所有的人尽快地全部转移到月球上。
Solution
天辣窝居然撸对了ctsc的题嗯这道题和小球问题是差不多的
首先按照时间拆开每个点,然后枚举时间t
对于同一太空站连容量为INF,枚举飞船分别连起点和终点,看最大流是不是比人数k多就行了
注意每一次枚举时间都要重新建图,就这样一个错误改了一星期,我还是太弱了
Code
#include <stdio.h> #include <string.h> #include <queue> #define rep(i, st, ed) for (int i = st; i <= ed; i += 1) #define erg(i, st) for (int i = ls[st]; i; i = e[i].next) #define fill(x, t) memset(x, t, sizeof(x)) #define min(x, y) (x)<(y)?(x):(y) #define INF 0x3f3f3f3f #define N 1001 #define E N * 21 + 1 struct edge{int x, y, w, next;}e[E]; int ls , pl , h ; inline void addEdge(int &cnt, int x, int y, int w){ cnt += 1; e[cnt] = (edge){x, y, w, ls[x]}; ls[x] = cnt; cnt += 1; e[cnt] = (edge){y, x, 0, ls[y]}; ls[y] = cnt; } using std:: queue; int dis ; inline int bfs(int st, int ed){ queue<int> que; que.push(st); fill(dis, -1); dis[st] = 1; while (!que.empty()){ int now = que.front(); que.pop(); erg(i, now){ if (e[i].w > 0 && dis[e[i].y] == -1){ dis[e[i].y] = dis[now] + 1; que.push(e[i].y); if (e[i].y == ed){ return 1; } } } } return 0; } int cur ; inline int find(int now, int ed, int mn){ if (now == ed || !mn){ return mn; } int ret = 0; for (int &i = cur[now]; i; i = e[i].next){ if (e[i].w > 0 && dis[now] + 1 == dis[e[i].y]){ int d = find(e[i].y, ed, min(mn - ret, e[i].w)); e[i].w -= d; e[i ^ 1].w += d; ret += d; if (ret == mn){ break; } } } return ret; } inline int dinic(int st, int ed, int n){ int tot = 0; while (bfs(st, ed)){ rep(i, 0, n){ cur[i] = ls[i]; } tot += find(st, ed, INF); } return tot; } int idx , plCnt ; int main(void){ int n, m, k; scanf("%d%d%d", &n, &m, &k); rep(i, 1, m){ scanf("%d%d", &h[i], &plCnt[i]); rep(j, 0, plCnt[i] - 1){ scanf("%d", &pl[i][j]); pl[i][j] += 1; } } n += 1; int cnt = 0; rep(t, 0, 50){ rep(j, 0, n){ idx[t][j] = ++ cnt; } } int st = idx[0][1]; int edgeCnt = 1; rep(t, 1, 50){ fill(ls, 0); edgeCnt = 1; rep(gg, 1, t){ rep(i, 0, n){ addEdge(edgeCnt, idx[gg - 1][i], idx[gg][i], INF); } rep(i, 1, m){ addEdge(edgeCnt, idx[gg - 1][pl[i][(gg - 1) % plCnt[i]]], idx[gg][pl[i][gg % plCnt[i]]], h[i]); } } int ed = idx[t][0]; int mxFlow = dinic(st, ed, cnt); if (mxFlow >= k){ printf("%d\n", t); return 0; } } puts("0"); return 0; }
相关文章推荐
- 【Codevs1034】家园(最大流,裂点)
- 【codevs1034】家园——网络流
- 【codevs1034】 家园
- 洛谷P2754 [CTSC1999]家园(最大流)
- codevs 2218 [CTSC1999] 补丁vs错误 dfs+二进制
- 【CTSC1999】 CODE[VS] 2218 补丁VS错误(状压最短路)
- CTSC1999/wiki1034 家园 题解 网络流+相对论
- [wikioi 1034][CTSC 1999]家园(网络流)
- 【codevs1034】星际转移问题(家园)(网络流)
- [网络流24题][CODEVS1922]骑士共存问题(最大流)
- codevs1907方格取数最大流
- 【codevs 2218】补丁vs错误(CTSC 1999)
- codevs 1017 乘积最大
- 【BZOJ2744】【codevs2366】朋友圈,二分图最大匹配
- CTSC 1999 家园 【网络流24题】星际转移
- [codevs1993]草地排水(最大流)
- 乘积最大codevs1017(noip2000)
- Code[VS] 1012 最小公倍数与最大公约数
- codevs2218 补丁vs错误 1999年CTSC国家队选拔赛[三星]
- Codevs 1993 草地排水 [dinic] [最大流]