洛谷 3305 「SDOI2013」费用流 发表于 2020.07.20 | 分类于 题解 | 过分显然的是,Bob 一定是把 \(P\) 全都分配在流量最大的那条边上…… 也就是在保证最大流的前提下,要流量最大的边的流量最小…… 二分一下答案(需要实数),与原来的容量取个 min 跑最大流。 代码: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586#include <cmath>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 100;const int M = 1e3;const double eps = 1e-5;int n,m,p,s,t;struct Edge{ int u,v,w;} e[M + 5];int to[(M << 1) + 5],pre[(M << 1) + 5],first[N + 5],cur[N + 5],edge_tot;double val[(M << 1) + 5];inline void add(int u,int v,double w){ int &tot = edge_tot; to[tot] = v,val[tot] = w,pre[tot] = first[u],first[u] = tot++;}int head,tail,q[N + 5],dep[N + 5],vis[N + 5];int bfs(){ head = tail = 0; memset(vis,0,sizeof vis); memset(dep,0x3f,sizeof dep); dep[s] = 0,vis[s] = 1,q[++tail] = s; for(register int p;head < tail;) { vis[p = q[++head]] = 0; for(register int i = first[p];~i;i = pre[i]) if(val[i] && dep[to[i]] > dep[p] + 1) { dep[to[i]] = dep[p] + 1; if(!vis[to[i]]) vis[to[i]] = 1,q[++tail] = to[i]; } } return dep[t] ^ 0x3f3f3f3f;}double dfs(int p,double flow){ if(p == t) return flow; double ret = 0,used = 0; for(register int i = cur[p];~i;cur[p] = i = pre[i]) if(val[i] > 0 && dep[to[i]] == dep[p] + 1 && (ret = dfs(to[i],min(flow - used,val[i]))) > 0) { used += ret,val[i] -= ret,val[i ^ 1] += ret; if(used >= flow) break; } return used;}double dinic(){ double ret = 0; while(bfs()) { for(register int i = 1;i <= n;++i) cur[i] = first[i]; ret += dfs(s,0x3f3f3f3f); } return ret;}int maxflow;double l,r,mid,ans;int check(){ memset(first,-1,sizeof first),edge_tot = 0; for(register int i = 1;i <= m;++i) add(e[i].u,e[i].v,min((double)e[i].w,mid)),add(e[i].v,e[i].u,0); double flow = dinic(); return fabs(flow - maxflow) < eps;}int main(){ memset(first,-1,sizeof first); scanf("%d%d%d",&n,&m,&p),s = 1,t = n; for(register int i = 1;i <= m;++i) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w),add(e[i].u,e[i].v,e[i].w),add(e[i].v,e[i].u,0); r = maxflow = dinic(); for(register int i = 1;i <= 100;++i) mid = (l + r) / 2,check() ? (ans = r = mid) : (l = mid); printf("%d\n%.4f\n",maxflow,ans * p);} 本文作者: Alpha1022 本文链接: https://www.alpha1022.me/articles/lg-3305.htm 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明出处!