POJ 2391 Ombrophobic Bovines(二分+拆点+最大流)
http://poj.org/problem?id=2391
题意:
给定一个无向图,点i处有Ai头牛,点i处的牛棚能容纳Bi头牛,求一个最短时间T,使得在T时间内所有的牛都能进到某一牛棚里去。
思路:
建立一个源点和汇点,源点和牛棚的初始牛量相连,汇点和牛棚容量相连。这样跑最大流,如果最后流量等于牛的总数时,就说明是可以的。
那么,怎么连边呢?
二分时间,根据时间来连边,所以首先我们先跑一遍floyd计算出两点距离。然后在该时间下,如果d【i】【j】,那么就添加边(i,i',INF),表面这段路是可以走的。
注意,这里是需要拆点的!!!

看这个建图,这个没有拆点,那么当我们的时间T=70的时候,只有(2,3)和(3,4)是满足的,但是在图中2-4也相连了,也就是说2-4也可以走,但事实上(2,4)这条路超过了时间设定。所以,不拆点是行不通的。
事实上,这个并不是一个二分图,任意点之间都可能有路径,所以需要拆点。
最后,注意这道题目的数据是很大的!!!
附上数据:http://contest.usaco.org/MAR05_4.htm
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
typedef pair<int,int> pll;
const LL INF=1e16;
const int maxn=+; int n,m;
int full_flow;
int s[maxn],t[maxn];
LL g[maxn][maxn]; struct Edge
{
int from,to,cap,flow;
Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
}; struct Dinic
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int cur[maxn];
int d[maxn]; void init(int n)
{
this->n=n;
for(int i=;i<n;++i) G[i].clear();
edges.clear();
} void AddEdge(int from,int to,int cap)
{
edges.push_back( Edge(from,to,cap,) );
edges.push_back( Edge(to,from,,) );
m=edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS()
{
queue<int> Q;
memset(vis,,sizeof(vis));
vis[s]=true;
d[s]=;
Q.push(s);
while(!Q.empty())
{
int x=Q.front(); Q.pop();
for(int i=;i<G[x].size();++i)
{
Edge& e=edges[G[x][i]];
if(!vis[e.to] && e.cap>e.flow)
{
vis[e.to]=true;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if(x==t || a==) return a;
int flow=, f;
for(int &i=cur[x];i<G[x].size();++i)
{
Edge &e=edges[G[x][i]];
if(d[e.to]==d[x]+ && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>)
{
e.flow +=f;
edges[G[x][i]^].flow -=f;
flow +=f;
a -=f;
if(a==) break;
}
}
return flow;
} int Maxflow(int s,int t)
{
this->s=s; this->t=t;
int flow=;
while(BFS())
{
memset(cur,,sizeof(cur));
flow +=DFS(s,0x3f3f3f3f);
}
return flow;
}
}DC; void floyd()
{
for (int k = ; k <= n; k++)
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
} void init(LL x)
{
DC.init(*n+); for(int i=;i<=n;i++)
{
DC.AddEdge(,i,s[i]);
DC.AddEdge(i+n,*n+,t[i]);
DC.AddEdge(i,i+n,0x3f3f3f3f);
} for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(g[i][j]<=x)
{
DC.AddEdge(i,j+n,0x3f3f3f3f);
DC.AddEdge(j,i+n,0x3f3f3f3f);
}
} int main()
{
//freopen("D:\\input.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
full_flow=;
for(int i=;i<=n;i++)
{
scanf("%d%d",&s[i],&t[i]);
full_flow+=s[i];
} for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
g[i][j]=INF;
g[i][i]=;
} for(int i=;i<m;i++)
{
int u,v;
LL w;
scanf("%d%d%lld",&u,&v,&w);
if(w<g[u][v]) g[u][v]=g[v][u]=w;
} floyd(); LL L=,R=;
LL ans=-; for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(g[i][j]!=INF) R=max(R,g[i][j]); while(L<=R)
{
LL mid=(L+R)/;
init(mid);
if(DC.Maxflow(,*n+)==full_flow)
{
ans=mid;
R=mid-;
}
else L=mid+;
}
printf("%I64d\n",ans);
} return ;
}
POJ 2391 Ombrophobic Bovines(二分+拆点+最大流)的更多相关文章
- POJ 2391 Ombrophobic Bovines (二分答案+floyd+最大流)
<题目链接> 题目大意: 给定一个有$n$个顶点和$m$条边的无向图,点$i$ 处有$A_i$头牛,点$i$ 处的牛棚能容纳$B_i$头牛,每条边有一个时间花费$t_i$(表示从一个端点走 ...
- 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
Ombrophobic Bovines Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18623 Accepted: 4 ...
- poj 2391 Ombrophobic Bovines 最短路 二分 最大流 拆点
题目链接 题意 有\(n\)个牛棚,每个牛棚初始有\(a_i\)头牛,最后能容纳\(b_i\)头牛.有\(m\)条道路,边权为走这段路所需花费的时间.问最少需要多少时间能让所有的牛都有牛棚可待? 思路 ...
- POJ 2391 Ombrophobic Bovines ( 经典最大流 && Floyd && 二分 && 拆点建图)
题意 : 给出一些牛棚,每个牛棚都原本都有一些牛但是每个牛棚可以容纳的牛都是有限的,现在给出一些路与路的花费和牛棚拥有的牛和可以容纳牛的数量,要求最短能在多少时间内使得每头牛都有安身的牛棚.( 这里注 ...
- POJ 2391 Ombrophobic Bovines【二分 网络流】
题目大意:F个草场,P条道路(无向),每个草场初始有几头牛,还有庇护所,庇护所有个容量,每条道路走完都有时间,问所有奶牛都到庇护所最大时间最小是多少? 思路:和POJ2112一样的思路,二分以后构建网 ...
随机推荐
- js嵌套轮播图
$(function(){ var navLi = $(".top_nav").find("li"), conDiv = $(".top_con&qu ...
- 如何查找元素对应事件的js代码
以chrome的firebug为例 1.找到其dom元素,然后右键"break on"-->"subtree modification"等,设置后元素旁边 ...
- fping命令测试主机存活
author:headsen chen date: 2018-10-09 20:11:22 1,测试一个范围内的主机: fping -a -g 192.168.1.1 192.168.1.255 ...
- sprintf函数详解
转摘声明:选自<CSDN 社区电子杂志——C/C++杂志> 在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望.由于sprintf 跟printf 在用法上几乎一样 ...
- hdu2196 Computer【树形DP】【换根法】
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- SQL---->mySQl数据库1------jdbc简单入门
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问. 目的:不用学习每个数据库的驱动,学 ...
- yii2 controller发送json数据给前端
最近要用yii2把之前老项目重构一下,因为前端打算用vuejs,所以Yii2前端那一套就放弃了,直接给前端传json数据 控制器代码: $response = Yii::$app->respon ...
- Database Partitioning Options DATABASE SHARDING
w主写从读.集群节点间时时内存复制.单表横切纵切.分析报表系统通过服务器联表 http://www.agildata.com/database-sharding/ Database Partition ...
- 三个在线django速成教程(转)
add by zhj: 除了这几个在线的,有些书也不错 1. Two Scoops of Django 2. Instant Django 1.5 Application Development St ...
- 《图解HTTP》书摘
图解HTTP 上野宣.于均良 1.3 网络基础 TCP/IP 2016-03-03 相互通信,双方就必须基于相同的方法.比如,如何探测到通信目标.由哪一边先发起通信.使用哪种语言进行通信.怎样结束通信 ...