POJ 2391 Ombrophobic Bovines (二分答案+floyd+最大流)
<题目链接>
题目大意:
给定一个有$n$个顶点和$m$条边的无向图,点$i$ 处有$A_i$头牛,点$i$ 处的牛棚能容纳$B_i$头牛,每条边有一个时间花费$t_i$(表示从一个端点走到另一个端点所需要的时间),求一个最短时间T使得在T时间内所有的牛都能进到某一牛棚里去。$(1 <= N <= 200, 1 <= M <= 1500,0 <= A_i <= 10^3, 0 <= B_i <= 10^3, 1 <= Dij <= 10^9)$。
解题分析:
很明显要二分答案,二分枚举最短的时间,然后用最大流去进行验证。将每个点$i$拆成两个点$i$和$i+n$,然后就是对于每次枚举的答案,进行重新建图,然后跑最大流,如果最大流等于所有牛的数量,则说明所有的牛都有牛棚能够停留,符合条件。建图的方法就是:超级源点向所有的点$i$连一条边,容量为i点初始牛的数量,所有点$i+n$向汇点连一条边,容量为该点牛的容量。因为点的数量很少,floyd预处理出任意两点之间的最短距离,然后对于每次枚举的时间T,最短距离小于等于T的边就加入网络,建好图之后,跑一遍最大流,进行判断。
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std; typedef long long ll;
const int N = ;
const ll INF = 1e18;
int n,m,st,ed;
int num[N],capa[N];
ll g[N][N],fullFlow; template<typename T>
inline void read(T&x){
x=;int f=;char c=getchar();
while(c<'' || c>''){ if(c=='-')f=-;c=getchar(); }
while(c>='' && c<=''){ x=x*+c-'';c=getchar(); }
x*=f;
}
struct Dinic
{
struct edge{ int from,to;ll cap,flow; };
vector<edge>es;
vector<int>G[N];
bool vis[N];
int g[N],iter[N];
void init(int n){
for(int i=; i<=n+; i++)G[i].clear();
es.clear();
}
void addedge(int from,int to,ll cap){
es.push_back((edge){from,to,cap,});
es.push_back((edge){to,from,,});
int x=es.size();
G[from].push_back(x-);
G[to].push_back(x-);
}
bool BFS(int s,int t){
memset(vis,,sizeof(vis));
queue <int> q;
vis[s]=;
g[s]=;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=; i<G[u].size(); i++){
edge &e=es[G[u][i]];
if(!vis[e.to]&&e.cap>e.flow){
vis[e.to]=;
g[e.to]=g[u]+;
q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int u,int t,ll f){
if(u==t||f==)return f;
int numflow=,d;
for(int &i=iter[u]; i<G[u].size(); i++){
edge &e=es[G[u][i]];
if(g[u]+==g[e.to]&&(d=DFS(e.to,t,min(f,e.cap-e.flow)))>){
e.flow+=d;
es[G[u][i]^].flow-=d;
numflow+=d;
f-=d;
if(f==)break;
}
}
return numflow;
}
int Maxflow(int s,int t){
int flow=;
while(BFS(s,t)){
memset(iter,,sizeof(iter));
int d=;
while(d=DFS(s,t,INF))flow+=d;
}
return flow;
}
}dinic; bool check(ll T){ //最长的时间限制
dinic.init(N);
for(int i=;i<=n;i++){
dinic.addedge(st,i,num[i]); //源点向每个点连一条边,容量为这个点的牛的数量
dinic.addedge(i+n,ed,capa[i]); //每个点拆点之后的点向汇点连一条边,容量为这个点能够容纳牛的数量
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(g[i][j]<=T) //将符合条件的边加上
dinic.addedge(i,j+n,INF);
return dinic.Maxflow(st,ed) == fullFlow; //判断是否满流,即是否所有的牛都有牛棚住
}
inline void Floyd(){ //floyd求出任意两点之间的最短距离
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(g[i][j]>g[i][k]+g[k][j])
g[i][j]=g[i][k]+g[k][j];
}
inline void Init(){
fullFlow = ;
st=,ed=*n+;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
g[i][j]=(i==j)?:INF; //初始化任意两点之间的距离
for(int i=;i<=n;i++){
read(num[i]);read(capa[i]);
fullFlow +=num[i]; //记录所有牛的数量
}
for(int i=;i<=m;i++){
int u,v;ll w;
read(u);read(v);read(w);
g[u][v]=g[v][u]=min(g[u][v],w);
}
Floyd();
}
int main(){
while(~scanf("%d%d",&n,&m)){
Init();
ll l=,r=;//二分的上下界
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(g[i][j]<INF)
r=max(r,g[i][j]); //找到时间的上界
ll ans=-; //二分答案
while(l<=r){
ll mid=(l+r)>>;
if(check(mid))ans=mid,r=mid-;
else l=mid+;
}
printf("%lld\n",ans);
}
}
POJ 2391 Ombrophobic Bovines (二分答案+floyd+最大流)的更多相关文章
- poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分, dinic, isap
poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分 dinic /* * Author: yew1eb * Created Time: 2014年10月31日 星期五 ...
- POJ 2391 Ombrophobic Bovines ★(Floyd+二分+拆点+最大流)
[题意]有n块草地,一些奶牛在草地上吃草,草地间有m条路,一些草地上有避雨点,每个避雨点能容纳的奶牛是有限的,给出通过每条路的时间,问最少需要多少时间能让所有奶牛进入一个避雨点. 和POJ2112很类 ...
- POJ 2391 Ombrophobic Bovines (Floyd + Dinic +二分)
Ombrophobic Bovines Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11651 Accepted: 2 ...
- poj 2391 Ombrophobic Bovines(最大流+floyd+二分)
Ombrophobic Bovines Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 14519Accepted: 3170 De ...
- POJ 2391 Ombrophobic Bovines(Floyd+二分+最大流)
题目链接 题意:农场有F(1 <= F <= 200)片草地用于放牛,这些草地有P(1 <= P <= 1500)连接,农场的草地上有一些避雨点,奶牛们可以在避雨点避雨,但是避 ...
- POJ 2391 Ombrophobic Bovines ( 经典最大流 && Floyd && 二分 && 拆点建图)
题意 : 给出一些牛棚,每个牛棚都原本都有一些牛但是每个牛棚可以容纳的牛都是有限的,现在给出一些路与路的花费和牛棚拥有的牛和可以容纳牛的数量,要求最短能在多少时间内使得每头牛都有安身的牛棚.( 这里注 ...
- POJ 2391 Ombrophobic Bovines
Ombrophobic Bovines Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18623 Accepted: 4 ...
- poj 2391 Ombrophobic Bovines【最大流】
我%--&(¥--,调了一下午,最后发现P赋值1e5能过,赋值1e6就会TLE致死.改了一下午加一晚上然而这是为什么??? 一种常见的建图套路,首先二分答案,注意上界要取大一点,1e9是不行的 ...
- POJ 2391 Ombrophobic Bovines(二分+拆点+最大流)
http://poj.org/problem?id=2391 题意: 给定一个无向图,点i处有Ai头牛,点i处的牛棚能容纳Bi头牛,求一个最短时间T,使得在T时间内所有的牛都能进到某一牛棚里去. 思路 ...
随机推荐
- Hdoj 1850.Being a Good Boy in Spring Festival 题解
Problem Description 一年在外 父母时刻牵挂 春节回家 你能做几天好孩子吗 寒假里尝试做做下面的事情吧 陪妈妈逛一次菜场 悄悄给爸爸买个小礼物 主动地 强烈地 要求洗一次碗 某一天早 ...
- BZOJ4259残缺的字符串
题目描述 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. ...
- CF765F Souvenirs
CF765F Souvenirs [CF765F]Souvenirs 主席树 - CQzhangyu - 博客园 其实不用主席树 感觉像是离线问题 但是不能支持差分.分治又处理不了 考虑按照右端点排序 ...
- Android TextView
常用属性 text:文本框中展示的文字 android:text="下载" android:text="@string/tv_text" ------- ...
- Fiddler--Composer
Composer选项卡支持手动构建和发请求:也可以在Session列表中拖拽Session放到Composer中,把该Session的请求复制到用户界面: 点击"execute"按 ...
- JN_0004:轻松解码类似eval(function(p,a,c,k,e,d){}))的JavaScript代码
百度访问统计代码JavaScript源码:红色加粗部分将是要修改的地方.eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"&qu ...
- Generator和Coroutine学习
简单的生产者消费者模型 #!/usr/bin/python2.7 def consumer(): while True: newn = yield print 'Consumer : {}'.form ...
- Nmpy函数总结
函数和方法method总览 这是个Numpy函数和方法分类排列目录. 创建数组 arange, array, copy, empty, empty_like, eye, fromfile, fromf ...
- JAVA写JSON的三种方法,java对象转json数据
JAVA写JSON的三种方法,java对象转json数据 转自:http://www.xdx97.com/#/single?bid=5afe2ff9-8cd1-67cf-e7bc-437b74c07a ...
- centos7.2 环境下两个数据库的安装部署
首先假如服务器上已经有一个 数据库mysql5.6.29,端口是3306. 接下来在安装一个mysql数据库,端口是3307的. 一:创建mysql编译目录 mkdir /usr/local/mysq ...