[POJ 2391]Ombrophobic Bovines[最大流][二分答案]
2016-04-07 10:06
387 查看
题目链接:[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,估计是优化过头出错误了。
具体代码如下:
题意分析:
有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];//注意是MAXM int 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; }
相关文章推荐
- linux第七章笔记
- mac 配置hadoop 2.6(单机和伪分布式)
- nginx安装教程
- 大学生应该学习python和linux而不是matlab和windows
- Linux下undefined reference to ‘pthread_create’问题解决
- 3.7.5 event_loop:事件循环
- linux内核设计第七周——可执行程序的装载
- Linux下undefine reference to 'FT_Init_FreeType'的解决办法
- 设置Tomcat内存
- 使用ToolRunner运行Hadoop程序基本原理分析
- 部署两个tomcat后,系统提示cannot set user id: Resource temporarily unavailable
- window.open的popup-only-once问题(document.cookie)
- linux下ls命令详解
- window.open详解
- Linux查看物理CPU个数、核数、逻辑CPU个数
- Linux应用服务器搭建手册—Weblogic服务域的创建与部署
- LINUX内核分析第七周学习总结:可执行程序的装载
- opencv sift 的实现与原理
- 《Linux内核设计与实现》第7章读书笔记
- log4cxx在ubuntu14.04中编译