POJ 2455 - Secret Milking Machine
2014-01-18 22:57
369 查看
原题地址:http://poj.org/problem?id=2455
题目大意:给出一个N个点的无向图,中间有P条边,要求找出从1到n的T条通路,满足它们之间没有公共边,并使得这些通路中经过的最长的边的长度最短。两点之间允许有重边
数据范围:2 <= N <= 200, 1 <= P <= 40,000,1 <= T <= 200,1 <= 每条路的长度L <= 1,000,000
题目分析:
看到“最大值最小”的第一反应就是二分最大长度k,满足T条通路没有公共边的第一反应就是将每条边的容量赋为1然后跑一遍最大流。这样算法就出来了:读入并建图,二分最大长度k,将所有长度小于等于 k 的边的容量设为1, 大于 k 的边容量设为0,然后以1为源点,n为汇点做一遍最大流,如果满足最大流大于等于T,则合要求继续二分,直至找出答案。
一开始在双向边建图的时候有点犹豫。毕竟网络流要求每条边必须要有反向边。最开始的想法是将每条双向边都拆成两条单向边,对每条单向边都建立一条长度为无穷大的反向边(无穷大是为了保证二分时赋初始容量都将它们为0),但是后来证明这种想法是错误的:因为题目要求每条边只能走一次,但是按我的想法每条边可以正向走一次,反向走一次,加上题目中允许有重边,就使情况变得更加复杂。后来我发现网络流的反向边不一定要初始容量为0——就算我将这一条双向边的两个方向按照网络流的一对反向边来建立,初始容量都允许为1,无论正着流还是反着流这条边所能允许的总容量必然只有0或1……然后就想通了(希望能给这里想不太清楚的同学们一点帮助)
然后这道题TLE到死……经过hockey指点才发现是我Dinic 写残了,应该到不能流的时候就退出但是我没有……改掉这一点之后,我加上当前弧优化的Dinic还是可以600+MS勉强AC的
PS:网上有些人说重新建立源点和汇点,并连接一条从源点到1的容量为T的边,其实丝毫没有必要,直接以1为源点是可以的
小结:建图还是需要多加思考多加练习,代码模板也是需要不断完善的,加油~
题目大意:给出一个N个点的无向图,中间有P条边,要求找出从1到n的T条通路,满足它们之间没有公共边,并使得这些通路中经过的最长的边的长度最短。两点之间允许有重边
数据范围:2 <= N <= 200, 1 <= P <= 40,000,1 <= T <= 200,1 <= 每条路的长度L <= 1,000,000
题目分析:
看到“最大值最小”的第一反应就是二分最大长度k,满足T条通路没有公共边的第一反应就是将每条边的容量赋为1然后跑一遍最大流。这样算法就出来了:读入并建图,二分最大长度k,将所有长度小于等于 k 的边的容量设为1, 大于 k 的边容量设为0,然后以1为源点,n为汇点做一遍最大流,如果满足最大流大于等于T,则合要求继续二分,直至找出答案。
一开始在双向边建图的时候有点犹豫。毕竟网络流要求每条边必须要有反向边。最开始的想法是将每条双向边都拆成两条单向边,对每条单向边都建立一条长度为无穷大的反向边(无穷大是为了保证二分时赋初始容量都将它们为0),但是后来证明这种想法是错误的:因为题目要求每条边只能走一次,但是按我的想法每条边可以正向走一次,反向走一次,加上题目中允许有重边,就使情况变得更加复杂。后来我发现网络流的反向边不一定要初始容量为0——就算我将这一条双向边的两个方向按照网络流的一对反向边来建立,初始容量都允许为1,无论正着流还是反着流这条边所能允许的总容量必然只有0或1……然后就想通了(希望能给这里想不太清楚的同学们一点帮助)
然后这道题TLE到死……经过hockey指点才发现是我Dinic 写残了,应该到不能流的时候就退出但是我没有……改掉这一点之后,我加上当前弧优化的Dinic还是可以600+MS勉强AC的
PS:网上有些人说重新建立源点和汇点,并连接一条从源点到1的容量为T的边,其实丝毫没有必要,直接以1为源点是可以的
//date 20140118 #include <cstdio> #include <cstring> const int maxn = 205; const int maxm = 80005; const int INF = 0x7FFFFFFF; inline int getint() { int ans(0); char w = getchar(); while('0' > w || w > '9')w = getchar(); while('0' <= w && w <= '9') { ans = ans * 10 + w - '0'; w = getchar(); } return ans; } inline int min(int a, int b){return a < b ? a : b;} inline int max(int a, int b){return a > b ? a : b;} int n, m, T; int s, t; struct edge { int v, w, c, next; }E[maxm]; int a[maxn]; int now[maxn]; int nedge; int lab[maxn]; inline void add(int u, int v, int w, int c) { E[++nedge].v = v; E[nedge].c = c; E[nedge].w = w; E[nedge].next = a[u]; a[u] = nedge; } int maxl, minl; inline int label() { static int q[maxn]; int l = 0, r = 1; memset(lab, 0xFF, sizeof lab); q[1] = s; lab[s] = 0; while(l < r) { int x = q[++l]; for(int i = a[x]; i; i = E[i].next) if(E[i].c == 1 && lab[E[i].v] == -1) { lab[E[i].v] = lab[x] + 1; q[++r] = E[i].v; } } return lab[t] != -1; } int Dinic(int v, int f) { if(v == t)return f; int res = 0, w; for(int i = now[v]; i; i = now[v] = E[i].next) if((E[i].c == 1) && (f > 0) && (lab[v] + 1 == lab[E[i].v]) && (w = Dinic(E[i].v, min(f, E[i].c)))) { E[i].c -= w; E[i ^ 1].c += w; f -= w; res += w; if(f == 0)break; } if(res == 0)lab[v] = -1; return res; } inline int max_flow() { int ans = 0; while(label()) { for(int i = s; i <= t; ++i)now[i] = a[i]; ans += Dinic(s, INF); } return ans; } inline bool check(int k) { for(int i = 2; i <= nedge; i += 2) if(E[i].w <= k)E[i].c = E[i ^ 1].c = 1; else E[i].c = E[i ^ 1].c = 0; int ans = max_flow(); //printf("%d\n", ans); return ans >= T; } inline int solve(int l, int r) { int mid; while(l < r) { mid = (l + r) >> 1; if(check(mid))r = mid; else l = mid + 1; } return l; } int main() { n = getint(); m = getint(); T = getint(); nedge = 1; maxl = 0; minl = INF; s = 1; t = n; int x, y, z; for(int i = 1; i <= m; ++i) { x = getint(); y = getint(); z = getint(); add(x, y, z, 0); add(y, x, z, 0); maxl = max(maxl, z); minl = min(minl, z); } int ans = solve(minl, maxl); printf("%d\n", ans); return 0; }
小结:建图还是需要多加思考多加练习,代码模板也是需要不断完善的,加油~
相关文章推荐
- POJ 2455 Secret Milking Machine (二分+无向图最大流)
- poj 2455 Secret Milking Machine(二分枚举+最大流)
- POJ 2455 Secret Milking Machine【二分+最大流】
- POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)
- POJ 2455 Secret Milking Machine (二分+无向图最大流)
- POJ-2455 Secret Milking Machine 二分+最大流
- 【网络流】 POJ 2455 Secret Milking Machine
- poj 2455 Secret Milking Machine 二分+最大流
- POJ 2455 Secret Milking Machine(搜索-二分,网络流-最大流)
- Poj 2455 Secret Milking Machine【二分+最大流】
- poj 2455 Secret Milking Machine 从1到n有多少条不同的路径(每条边走一次) 网络流 cap赋值为1
- POJ 2455 Secret Milking Machine
- Secret Milking Machine POJ - 2455
- poj 2455 Secret Milking Machine
- POJ 2455 Secret Milking Machine (二分答案+最大流)
- POJ-2455-Secret Milking Machine
- POJ 2455--Secret Milking Machine【二分枚举 && 最大流 && 经典】
- POJ 2455 Secret Milking Machine
- POJ 2455 Secret Milking Machine(二分+最大流)
- POJ 2455 Secret Milking Machine(最大流+二分)