【poj2391】【最大流】Ombrophobic Bovines
来源:互联网 发布:ubuntu 不识别分区 编辑:程序博客网 时间:2024/05/21 17:28
这道题可以转换为网络流判定性问题。
首先二分出一个最短时间mtime,然后将图中的每个点拆为两个,令a[i]为当前牛的数量,b[i]为容纳最大牛的数量,len[a][b]为点a到点b的最短距离,tot为牛的总数。
首先floyd求出两点间的最短距离,然后对于每一个点,连边(s,i,a[i]),(i,t,b[i]),(i,i + n,∞)然后若len[i][j] < mtime,连一条(i,j + n,∞)的边,跑一次最大流。如果maxflow =tot,则说明可以在该时间下可行,这样迭代下去,就求出最短时间了。
代码:
#include<cstdio>#include<cstring>using namespace std;const long long inf = 0x3f3f3f3f3f3f3f3fll;const int maxn = 500;const int maxf = 0x3f3f3f3f;long long len[maxn][maxn];int cur[maxn],dis[maxn],gap[maxn],pre[maxn];int a[maxn],b[maxn];int cap[maxn][maxn];long long ans,limit;int n,m,tot;int s,t;void init(){freopen("poj2391.in","r",stdin);freopen("poj2391.out","w",stdout);}void floyd(){for(int k = 1;k <= n;k++){for(int i = 1;i <= n;i++){for(int j = 1;j <= n;j++){if(i == j || i == k || j == k)continue;if(len[i][k] + len[k][j] < len[i][j])len[i][j] = len[i][k] + len[k][j];}}}}inline int min(int a,int b){return a < b ? a : b; }int sap(){memset(cur,0,sizeof(cur));memset(dis,0,sizeof(dis));memset(gap,0,sizeof(gap));int u = pre[s] = s,maxflow = 0,aug = maxf;int nodenum = 2 * n + 2;gap[0] = nodenum;while(dis[s] < nodenum){loop: for(int v = cur[u];v < nodenum;v++){if(cap[u][v] && dis[u] == dis[v] + 1){cur[u] = v;aug = min(aug,cap[u][v]);pre[v] = u;u = v;if(v == t){maxflow += aug;for(u = pre[u];v != s;v = u,u = pre[u]){cap[u][v] -= aug;cap[v][u] += aug;}aug = maxf;}goto loop;}}int mind = nodenum;for(int v = 1;v < nodenum;v++){if(cap[u][v] && (mind > dis[v])){cur[u] = v;mind = dis[v];}}if((--gap[dis[u]]) == 0)break;gap[dis[u] = mind + 1]++;u = pre[u];}return maxflow;}void calc(){long long l = 0,r = limit + 1,mid;while(l < r){mid = (l + r) >> 1;memset(cap,0,sizeof(cap));for(int i = 1;i <= n;i++){cap[s][i] = a[i];cap[i][i + n] = (maxf >> 1);cap[i + n][t] = b[i]; }for(int i = 1;i <= n;i++){for(int j = 1;j <= n;j++){if(i != j && len[i][j] <= mid)cap[i][j + n] = (maxf >> 1);}}int tmp = sap();if(tmp == tot)ans = mid,r = mid;else l = mid + 1;}printf("%lld\n",ans);}void readdata(){while(scanf("%d%d",&n,&m) == 2){limit = 0;s = 0,t = 2 * n + 1,tot = 0,ans = -1;for(int i = 1;i <= n;i++){for(int j = 1;j <= n;j++){if(i == j)len[i][j] = 0;else len[i][j] = inf;}}for(int i = 1;i <= n;i++){scanf("%d%d",&a[i],&b[i]);tot += a[i];}for(int j = 1;j <= m;j++){long long u,v,w;scanf("%lld%lld%lld",&u,&v,&w);if(len[u][v] > w){len[u][v] = len[v][u] = w;limit += w;}}floyd();calc();}}int main(){init();readdata();return 0;}
- 【poj2391】【最大流】Ombrophobic Bovines
- POJ2391 Ombrophobic Bovines 二分+最大流dinic
- poj2391 Ombrophobic Bovines(二分+floyd+最大流)
- 【poj2391】Ombrophobic Bovines 二分+最大流+floyd
- 【POJ2391】Ombrophobic Bovines【二分】【Floyd】【最大流】
- [网络流]poj2391 Ombrophobic Bovines
- POJ2391 Ombrophobic Bovines(二分+拆点+最大流)
- POJ2391:Ombrophobic Bovines floyd+二分答案+最大流
- poj2391 Ombrophobic Bovines 拆点+网络流
- poj2391 Ombrophobic Bovines
- POJ2391 Ombrophobic Bovines
- POJ2391.Ombrophobic Bovines(不喜欢雨的奶牛)——floyd+二分+拆点+最大流
- ACM->最大流 Ombrophobic Bovines
- 解题报告 之 POJ2391 Ombrophobic Bovines
- POJ2391 Ombrophobic Bovines 网络流拆点+二分+floyed
- POJ 2391 Ombrophobic Bovines(最大流)
- poj 2391 Ombrophobic Bovines 二分+最大流
- POJ 2391 Ombrophobic Bovines 最大流+二分
- Shell 仿消灭星星游戏(2013-03-15)
- linux下编译出现 "警告:隐式声明与内建函数'exit'不兼容" 的解决方法
- android震动代码分析
- uva 11520 Fill the Square
- MySQL平台数据库备份方案详细说明
- 【poj2391】【最大流】Ombrophobic Bovines
- PhoneGap开发总结(干货)
- poj 3083 Children of the Candy Corn 解题报告-- DFS BFS
- 修改和重新封装了一个GHOST XP
- 山穷水尽疑无路,柳暗花明遇JEECG
- 利用外部邮箱发送邮件的方法
- {linux应用编程} 进程和线程总结
- 关于Hibernate的关联问题
- 孙悟空的成长历程想到的