标签:
这道题的意思是给你一个有向图, 每条边上有一个最大载重量, 现在有x头牛要从顶点1走向顶点n, 每头牛要载的重量都是一样的, 问你最多能载多少的重量? 可以二分答案, 算出每头牛的载重, 然后修改边权, 跑一次最大流即可判断当前答案是否正确, 二分答案即可, 注意由于原始边权/每头牛的载重量可能会很大, 因此我们在修改边权时应该注意这一点,将边权的最大值控制在1000000之内, 防止溢出, 代码如下:
#include <bits/stdc++.h> using namespace std; const int maxn = 100; int n, m, x; struct Dinic{ int n; struct edge {int from, to, cap;}; vector<int> G[maxn]; vector<edge> e; int level[maxn], iter[maxn]; void init() { for(int i=0; i<=n; i++) G[i].clear(); e.clear(); } void add_edge(int u, int v, int cap){ e.push_back((edge){u, v, cap}); e.push_back((edge){v, u, 0}); int m = e.size(); G[u].push_back(m-2); G[v].push_back(m-1); } void bfs(int s){ memset(level, -1, sizeof(level)); queue<int> que; level[s] = 0; que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); for(int i=0; i<G[u].size(); i++) { edge &te = e[G[u][i]]; if(te.cap>0 && level[te.to]<0){ level[te.to] = level[u] + 1; que.push(te.to); } } } } int dfs(int v, int t, int f){ if(v == t) return f; for(int &i=iter[v]; i<G[v].size(); i++){ edge &tpe = e[G[v][i]]; if(tpe.cap>0 && level[v]<level[tpe.to]){ int d = dfs(tpe.to, t, min(f, tpe.cap)); if(d > 0) { tpe.cap -= d; e[G[v][i]^1].cap += d; return d; } } } return 0; } int max_flow(int s, int t){ int flow = 0; for( ;; ){ bfs(s); if(level[t]<0) return flow; memset(iter, 0, sizeof(iter)); int f; while((f=dfs(s, t, 0x3f3f3f3f)) > 0) flow += f; } } }di, di2; bool check(double mid) { double eve = mid/(double)x; di2 = di; for(int i=0; i<di2.e.size(); i++) { di2.e[i].cap = min((double)di2.e[i].cap/eve, (double)1000000+100); } // printf(" ----------- \n"); // for(int i=0; i<di2.e.size(); i++) { // if(di2.e[i].cap) printf("%d %d %d\n", di2.e[i].from, di2.e[i].to, di2.e[i].cap); // } int res = di2.max_flow(1, n); return res >= x; } int main() { scanf("%d%d%d", &n, &m, &x); di.n = n; di.init(); for(int i=0; i<m; i++){ int u, v, c; scanf("%d%d%d", &u, &v, &c); di.add_edge(u, v, c); } double l=0, r=(double)0x3f3f3f3f; double res = 0; for(int i=0; i<1000; i++) { double mid = (l+r)/2; if(check(mid)){ res = mid; l = mid; } else r = mid; } printf("%.10f\n", res); return 0; }
IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) 二分答案 + 网络流
标签:
原文地址:http://www.cnblogs.com/xingxing1024/p/5299564.html