POJ2391
来源:互联网 发布:淘宝聚划算怎么买 编辑:程序博客网 时间:2024/06/07 09:26
Problem : Ombrophobic Bovines
Description : 有N个点,每个点都有一些老鼠和一些能容纳老鼠的地方,现在,下午了,老鼠要在规定时间内都找到自己的容纳点,每个点到每个点都有一定的到达时间,现在问你最少要多少时间才能完成这项工作,如果不能完成,输出“-1”。
Solution : Floyd+二分枚举+网络最大流。这题是我的一个学习题。感觉网络流的应用真的是太广了。Floyd不用多说,先求出每个点到每个点的最短路径,然后就是利用每个点老鼠的数量和容纳点的数目来建图。注意!这里要拆点,不然过不了。这个其实也很简单,我们枚举最短时间是为了网络流中的加边。如果小于这个时间就连边,那么如果是这样一种情况:1->2=40, 2->3=70,最短时间是110。那么我们只会加入1->2和2->3这两条边,但是如果不拆点,1->3就会间接连边了。这样不符合我们的要求,那么拆点就可以完美解决这个问题,拆点一般用于任意两点都可以到达的情况。随后就是套最大流的模板了。注意,这里我二分枚举最短时间的时候用了下离散化。这题让我最蛋疼的是交G++WA,C++AC。我都不知道什么鬼。
Code(C++) :
#include <stdio.h>#include <string.h>#include <iostream>#include <queue>#include <set>#define MIN(a,b) ((a)>(b)? (b):(a))using namespace std;typedef long long LL;const int SIZE=200*3+100;const LL INF=(1LL<<60);const int M=200*2+5;int src,des;int d[SIZE];int n;int MAP[SIZE][SIZE];int F,P;int a[M],b[M];LL map[M][M];LL line[M*M];int top;int SUM;void build(LL x){ src=0; des=2*F+1; n=2*F; memset(MAP,0,sizeof(MAP)); for(int i=1;i<=F;i++) MAP[src][i]=a[i], MAP[i+F][des]=b[i]; for(int i=1;i<=F;i++) for(int j=1;j<=F;j++) if(map[i][j]<=x) MAP[i][j+F]=SUM;}bool bfs(int src,int des){ memset(d,-1,sizeof(d)); queue<int> que; que.push(src); d[src]=0; while(!que.empty()){ int now=que.front(); que.pop(); for(int i=0;i<=1+n;i++) if(d[i]==-1&&MAP[now][i]>0){ d[i]=d[now]+1; que.push(i); } } return d[des]>=0;}int dfs(int t,int sum,int des){ if(t==des) return sum; int tmp=sum; for(int i=0;i<=n+1&∑i++) if(d[i]==d[t]+1&&MAP[t][i]>0){ int a=dfs(i,MIN(sum,MAP[t][i]),des); MAP[t][i]-=a; MAP[i][t]+=a; sum-=a; } return tmp-sum;}int DINIC(int src,int des){ int sum=0; while(bfs(src,des)) sum+=dfs(src,SUM,des); return sum;}void floyd(){ for(int k=1;k<=F;k++) for(int i=1;i<=F;i++) for(int j=1;j<=F;j++) map[i][j]=MIN(map[i][j],map[i][k]+map[k][j]);}bool judge(LL x){ build(x); return DINIC(src,des)==SUM;}void work(){ SUM=0; for(int i=1;i<=F;i++) scanf("%d%d",&a[i],&b[i]), SUM+=a[i]; for(int i=1;i<=F;i++){ for(int j=1;j<=F;j++) map[i][j]=INF; map[i][i]=0; } int x,y; LL v; for(int i=1;i<=P;i++) scanf("%d%d%I64d",&x,&y,&v), map[x][y]=map[y][x]=MIN(MIN(map[x][y],map[y][x]),v); floyd(); set<LL> has_set; for(int i=1;i<=F;i++) for(int j=i+1;j<=F;j++) if(map[i][j]<INF) has_set.insert(map[i][j]); top=0; for(set<LL>::iterator it=has_set.begin();it!=has_set.end();++it) line[top++]=*it; int l=0,r=top-1,mid; int ans=-1; while(l<=r){ mid=(l+r)/2; if(judge(line[mid])) ans=mid, r=mid-1; else l=mid+1; } if(ans==-1) puts("-1"); else printf("%I64d\n",line[ans]);}int main(){ //freopen("in.data","r",stdin); while(~scanf("%d%d",&F,&P)) work(); return 0;}
0 0
- POJ2391
- poj2391
- POJ2391
- poj2391 Ombrophobic Bovines
- poj2391 二分+floyd+dinic
- POJ2391解题报告
- POJ2391 Ombrophobic Bovines
- 【poj2391】【最大流】Ombrophobic Bovines
- [网络流]poj2391 Ombrophobic Bovines
- poj2391(网络流+犀利建图)
- POJ2391 Ombrophobic Bovines 二分+最大流dinic
- poj2391 Ombrophobic Bovines 拆点+网络流
- poj2391 二分+拆点+网络流
- POJ2391 Floyd+离散化+二分+DINIC
- 解题报告 之 POJ2391 Ombrophobic Bovines
- POJ2391 Ombrophobic Bovines 网络流拆点+二分+floyed
- poj2391 Ombrophobic Bovines(二分+floyd+最大流)
- 【poj2391】Ombrophobic Bovines 二分+最大流+floyd
- bfs算法【解析】
- vs2010 自动关闭 无法加载dll uiautomationcore.dll
- TCP/IP与HTTP
- spring容器归纳(三)
- 【LeetCode】 021. Merge Two Sorted Lists
- POJ2391
- 一次系统安装记——TPM阻止系统安装
- 关于文件路径的反斜杠正斜杠和双斜杠问题
- 分享一个转换数字格式的函数,将任意数字转化为5.00样式的数字
- 七牛-简单上传(java)
- C语言中的指针
- TCP/IP详解--TCP/IP中三次握手 四次握手状态分析
- 自定义view,drawtext中文字上方多两个横杠
- 更改oracle账户密码