[POJ 2391]Ombrophobic Bovines[最大流][二分答案]
来源:互联网 发布:unity3d 性能分析 编辑:程序博客网 时间:2024/05/09 03:05
题目链接:[POJ 2391]Ombrophobic Bovines[最大流][二分答案]
题意分析:
有F个地区,每个地区有have[i]头牛,可以提供can[i]头牛的庇护,有P条连接各个地区的无向道路,问:所有牛都能得到庇护,最少需要多少时间?
解题思路:
源点和牛间连一条容量为have[i]的边,汇点到牛间连一条容量为can[i]的边,需要将牛拆点(否则会发生串流,2->3 and 3->4 != 2->4)。用floyd预处理任意点间最短距离,二分答案,每次将距离小于等于答案的边添加进入图中,求最大流即可。如果满流就缩小答案,否则扩大答案。
个人感受:
第一想法是费用流,每次最大流的时候更新这条流的价值和到答案。然后写完WA了几发,自己给了自己一个反例:
3 3
2 2
0 2
2 0
1 2 10
3 1 10
3 2 100
ans: 10
然后floyd竟然写错了,太自信了= =。另外,网上一些过于优化的SAP也会WA,估计是优化过头出错误了。
具体代码如下:
#include<algorithm>#include<cctype>#include<cmath>#include<cstdio>#include<cstring>#include<iomanip>#include<iostream>#include<map>#include<queue>#include<set>#include<sstream>#include<stack>#include<string>#define lowbit(x) (x & (-x))#define ll long long#define pr(x) cout << #x << " = " << (x) << '\n';using namespace std;const int MAXN = 510;//点数的最大值const int MAXM = 540010;//边数的最大值const long long INF = 1e16;struct Edge{ int to,next,cap,flow;}edge[MAXM];//注意是MAXMint tol, src, des;int head[MAXN];int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];void init(){ tol = 0; memset(head,-1,sizeof(head));}//加边,单向图三个参数,双向图四个参数void addedge(int u,int v,int w,int rw=0){ edge[tol].to = v;edge[tol].cap = w;edge[tol].next = head[u]; edge[tol].flow = 0;head[u] = tol++; edge[tol].to = u;edge[tol].cap = rw;edge[tol].next = head[v]; edge[tol].flow = 0;head[v]=tol++;}//输入参数:起点、终点、点的总数//点的编号没有影响,只要输入点的总数int sap(int start,int end,int N){ memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u = start; pre[u] = -1; gap[0] = N; int ans = 0; while(dep[start] < N) { if(u == end) { int Min = INF; for(int i = pre[u];i != -1; i = pre[edge[i^1].to]) if(Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow; for(int i = pre[u];i != -1; i = pre[edge[i^1].to]) { edge[i].flow += Min; edge[i^1].flow -= Min; } u = start; ans += Min; continue; } bool flag = false; int v; for(int i = cur[u]; i != -1;i = edge[i].next) { v = edge[i].to; if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) { flag = true; cur[u] = pre[v] = i; break; } } if(flag) { u = v; continue; } int Min = N; for(int i = head[u]; i != -1;i = edge[i].next) if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if(!gap[dep[u]])return ans; dep[u] = Min+1; gap[dep[u]]++; if(u != start) u = edge[pre[u]^1].to; } return ans;}int have[MAXN], can[MAXN], f, sum;ll mp[MAXN][MAXN];void build(ll up) { init(); for (int i = 1; i <= f; ++i) { addedge(src, i, have[i]); addedge(i + f, des, can[i]); addedge(i, i + f, sum); for (int j = i + 1; j <= f; ++j) { if (mp[i][j] <= up) { addedge(i, j + f, sum); addedge(j, i + f, sum); } } }}int main(){ int m; while (~scanf("%d%d", &f, &m)) { sum = 0; for (int i = 1; i <= f; ++i) { scanf("%d%d", &have[i], &can[i]); sum += have[i]; } int u, v, w; for (int i = 1; i <= f; ++i) for (int j = 1; j <= f; ++j) mp[i][j] = INF; for (int i = 0; i < m; ++i) { scanf("%d%d%d", &u, &v, &w); if (w < mp[u][v]) mp[u][v] = mp[v][u] = w; } src = 0, des = 2 * f + 1; for (int i = 1; i <= f; ++i) { for (int j = 1; j <= f; ++j) { for (int k = 1; k <= f; ++k) mp[j][k] = min(mp[j][i] + mp[i][k], mp[j][k]); } } ll ans = -1; ll l = 1, r = INF - 1, mid; while (l <= r) { mid = (l + r) / 2; build(mid); if (sap(src, des, des + 1) >= sum) { ans = mid; r = mid - 1; } else l = mid + 1; } printf("%lld\n", ans); } return 0;}
0 0
- POJ 2391 Ombrophobic Bovines 拆点建图,二分答案,最大流
- POJ 2391 Ombrophobic Bovines (最大流+二分答案)
- [POJ 2391]Ombrophobic Bovines[最大流][二分答案]
- poj 2391 Ombrophobic Bovines 二分+最大流
- POJ 2391 Ombrophobic Bovines 最大流+二分
- POJ--2391[Ombrophobic Bovines] Floyd+最大流判定(拆点)+二分答案
- POJ--2391--Ombrophobic Bovines【拆点+Floyd+Dinic优化+二分答案】网络最大流
- POJ-2391 Ombrophobic Bovines (二分答案+Floyd+拆点+最大流)
- POJ 2391 Ombrophobic Bovines 网络流 二分答案
- POJ 2391 - Ombrophobic Bovines(网络流’最大流+Floyd+二分)
- poj 2391 Ombrophobic Bovines(floyd+二分+最大流)
- POJ 2391 Ombrophobic Bovines (二分+最短路+最大流)
- poj 2391 Ombrophobic Bovines(二分+最大流)
- POJ 2391 - Ombrophobic Bovines Floyd+二分+加点构图最大流.
- poj 2391 Ombrophobic Bovines 二分+拆点建图+最大流
- POJ 2391 Ombrophobic Bovines(二分+floyd+最大流)
- 【最大流+最短路+二分】POJ-2391 Ombrophobic Bovines
- POJ 2391 Ombrophobic Bovines 二分最大流+拆点
- 两年后,再议“站内信”的实现
- 正则表达式使用
- 光标形状汇总
- poj2533 LIS
- boa安装注意
- [POJ 2391]Ombrophobic Bovines[最大流][二分答案]
- 使用ToolRunner运行Hadoop程序基本原理分析
- poj1458 LCS
- C#像QQ一样隐藏窗体
- 全国和国际天气预报API免费接口
- 3.7.4 event_request_timer:安排定时事件
- Spring源代码解析(二):IoC容器在Web容器中的启动
- C#创建不规则窗体-图片
- hdu1167 dp