链接:http://poj.org/problem?id=2112

题意:有k个挤奶器。编号1~k,c头牛,编号k+1~k+c,每一个挤奶器最多能给m头牛挤奶,给你一个k+c的邻接矩阵。要求每头牛都能挤奶而且要求c头牛须要走的全部路程中的最大路程最小,求这个最小的路。

思路:

1. 先用floyd处理出多源最短路

2. 用二分枚举答案的可能。初始上限应该为(200+30)*200。可是我这么开T了,可能由于代码太挫,改到1000,卡着时间过了,仅仅能说poj数据弱了。后来看别人的代码。和我的做法一样可是用了邻接表。就能设上限为40000了。在二分中:

(1)构造容量网络,以0点为源点。到每头牛的容量为1。以n+1点为汇点。每一个挤奶器到汇点的容量为m,当然反过来也能够,由于源点和汇点的流量是相等的(等于c)。对于每头牛和每一个挤奶器之间的距离,假设比枚举的距离还大。则容量为0,否则容量为1。

(2)Dinic找出网络最大流,非常明显最大流最大是c,当最大流是c的时候是一种答案。但不一定是最优。更新二分上限。假设最大流没达到c,则更新下限。

这是做完POJ2391知道了Dinic优化。改进后的写法。优化了三个地方:容量网络改为邻接表、Dinic优化、二分上限从floyd中返回,157MS ,我原以为Dinic优化应该是效率提高的主要原因。把Dinic优化去掉单纯用邻接表。266MS。原来邻接表才是这道题效率提高的主要原因,可是Dinic优化还是非常实用的。

假设floyd再加个剪枝,能够跑110MS

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 200100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 131
#define mod 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 struct node{
int u,w,next;
}edge[MAXN];
int head[350],e[350][350];
int dist[350];
int cnt,n,m,k,c,src,sink;
void add_edge(int a,int b,int c){
edge[cnt].u = b;
edge[cnt].w = c;
edge[cnt].next = head[a];
head[a] = cnt++;
}
int floyd(){
int i,j,k;
int maxm = 0;
for(k=1;k<=n;k++){
for(i=1;i<=n;i++){
if(e[i][k]==INF) continue;
for(j=1;j<=n;j++){
if(e[k][j]!=INF&&e[i][k]+e[k][j]<e[i][j]){
e[i][j] = e[i][k] + e[k][j];
if(e[i][j]>maxm) maxm = e[i][j];
}
}
}
}
return maxm;
}
void build_graph(int minm){
int i,j;
memset(head,-1,sizeof(head));
cnt = 0;
for(i=1;i<=k;i++){
add_edge(i,n+1,m);
add_edge(n+1,i,0);
}
for(i=k+1;i<=n;i++){
add_edge(0,i,1);
add_edge(i,0,0);
}
for(i=k+1;i<=n;i++){
for(j=1;j<=k;j++){
if(e[i][j]<=minm){
add_edge(i,j,1);
add_edge(j,i,0);
}
}
}
}
int bfs(){
int i,j;
memset(dist,-1,sizeof(dist));
queue<int>q;
q.push(0);
dist[0] = 1;
while(!q.empty()){
int t = q.front();
q.pop();
for(i=head[t];i!=-1;i=edge[i].next){
if(dist[edge[i].u]==-1&&edge[i].w){
dist[edge[i].u] = dist[t] + 1;
q.push(edge[i].u);
}
}
}
if(dist[n+1]!=-1) return 1;
else return 0;
}
int dfs(int u,int delta){
int i,j;
int dd;
if(u==n+1) return delta;
for(i=head[u];i!=-1;i=edge[i].next){
if(dist[edge[i].u]==dist[u]+1&&edge[i].w&&(dd = dfs(edge[i].u,min(edge[i].w,delta)))){
edge[i].w -= dd;
edge[i^1].w += dd;
return dd;
}
}
dist[u] = -1;
return 0;
}
int main(){
int i,j;
while(scanf("%d%d%d",&k,&c,&m)!=EOF){
n = k + c;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
scanf("%d",&e[i][j]);
if(e[i][j]==0) e[i][j] = INF;
}
}
int mid, l = 0,r=floyd();
int sum,temp;
while(l<r){
mid = (l+r)/2;
sum = 0;
build_graph(mid);
while(bfs()){
while(1){
temp = dfs(0,INF);
if(!temp) break;
sum += temp;
}
}
if(sum>=c) r = mid;
else l = mid + 1;
}
printf("%d\n",l);
}
return 0;
}

之前的写法,1875MS擦边过了。

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 50100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define seed 131
#define mod 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 int edge[300][300],customer[300][300];
int vis[300],dist[300][300];
int n,m,k,c;
void floyd(){
int i,j,k;
for(k=1;k<=n;k++){
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(edge[i][k]!=INF&&edge[k][j]!=INF&&edge[i][k]+edge[k][j]<edge[i][j])
edge[i][j] = edge[i][k] + edge[k][j];
}
}
}
}
void build_graph(int minm){
int i,j;
memset(customer,0,sizeof(customer));
for(i=1;i<=k;i++) customer[i][n+1] = m;
for(i=k+1;i<=n;i++) customer[0][i] = 1;
for(i=k+1;i<=n;i++){
for(j=1;j<=k;j++){
if(edge[i][j]<=minm) customer[i][j] = 1;
}
}
}
int bfs(){
int i,j;
memset(vis,0,sizeof(vis));
memset(dist,0,sizeof(dist));
queue<int>q;
q.push(0);
vis[0] = 1;
while(!q.empty()){
int t = q.front();
q.pop();
for(i=0;i<=n+1;i++){
if(!vis[i]&&customer[t][i]){
vis[i] = 1;
dist[t][i] = 1;
q.push(i);
}
}
}
if(vis[n+1]) return 1;
else return 0;
}
int dfs(int u,int delta){
int i,j,s;
if(u==n+1) return delta;
s = delta;
for(i=0;i<=n+1;i++){
if(dist[u][i]){
int dd = dfs(i,min(customer[u][i],delta));
customer[u][i] -= dd;
customer[i][u] += dd;
delta -= dd;
}
}
return s - delta;
}
int main(){
int i,j;
while(scanf("%d%d%d",&k,&c,&m)!=EOF){
n = k + c;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
scanf("%d",&edge[i][j]);
if(edge[i][j]==0) edge[i][j] = INF;
}
}
floyd();
int mid, l = 0, r = 10000;
int sum;
while(l<r){
mid = (l+r)/2;
sum = 0;
build_graph(mid);
while(bfs()) sum += dfs(0,INF);
if(sum==c) r = mid;
else l = mid + 1;
}
printf("%d\n",l);
}
return 0;
}

POJ--2112--Optimal Milking【Floyd+Dinic+二分答案】的更多相关文章

  1. POJ 2112 Optimal Milking (Dinic + Floyd + 二分)

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 19456   Accepted: 6947 ...

  2. POJ 2112 Optimal Milking (Floyd+二分+最大流)

    [题意]有K台挤奶机,C头奶牛,在奶牛和机器间有一组长度不同的路,每台机器每天最多能为M头奶牛挤奶.现在要寻找一个方案,安排每头奶牛到某台机器挤奶,使得C头奶牛中走过的路径长度的和的最大值最小. 挺好 ...

  3. POJ 2112 Optimal Milking【网络流+二分+最短路】

    求使所有牛都可以被挤牛奶的条件下牛走的最长距离. Floyd求出两两节点之间的最短路,然后二分距离. 构图: 将每一个milking machine与源点连接,边权为最大值m,每个cow与汇点连接,边 ...

  4. POJ 2112 Optimal Milking 最短路 二分构图 网络流

    题意:有C头奶牛,K个挤奶站,每个挤奶器最多服务M头奶牛,奶牛和奶牛.奶牛和挤奶站.挤奶站和挤奶站之间都存在一定的距离.现在问满足所有的奶牛都能够被挤奶器服务到的情况下,行走距离的最远的奶牛的至少要走 ...

  5. POJ 2112 Optimal Milking(最大流+二分)

    题目链接 测试dinic模版,不知道这个模版到底对不对,那个题用这份dinic就是过不了.加上优化就WA,不加优化TLE. #include <cstdio> #include <s ...

  6. POJ 2112 Optimal Milking (二分 + floyd + 网络流)

    POJ 2112 Optimal Milking 链接:http://poj.org/problem?id=2112 题意:农场主John 将他的K(1≤K≤30)个挤奶器运到牧场,在那里有C(1≤C ...

  7. Poj 2112 Optimal Milking (多重匹配+传递闭包+二分)

    题目链接: Poj 2112 Optimal Milking 题目描述: 有k个挤奶机,c头牛,每台挤奶机每天最多可以给m头奶牛挤奶.挤奶机编号从1到k,奶牛编号从k+1到k+c,给出(k+c)*(k ...

  8. POJ 2112 Optimal Milking (二分+最短路径+网络流)

    POJ  2112 Optimal Milking (二分+最短路径+网络流) Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K To ...

  9. POJ 2112—— Optimal Milking——————【多重匹配、二分枚举答案、floyd预处理】

    Optimal Milking Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Sub ...

  10. POJ 2112 Optimal Milking ( 经典最大流 && Floyd && 二分 )

    题意 : 有 K 台挤奶机器,每台机器可以接受 M 头牛进行挤奶作业,总共有 C 头奶牛,机器编号为 1~K,奶牛编号为 K+1 ~ K+C ,然后给出奶牛和机器之间的距离矩阵,要求求出使得每头牛都能 ...

随机推荐

  1. devenv.exe 编译Solution

    Build https://docs.microsoft.com/en-us/visualstudio/ide/reference/build-devenv-exe Builds a solution ...

  2. 国内物联网平台初探(七) ——Ablecloud物联网自助开发和大数据云平台

    平台定位 面向IoT硬件厂商,提供设备联网与管理.远程查看控制.定制化云端功能开发.海量硬件数据存储与分析等基础设施,加速硬件实现联网智能化. 架构 服务 云端服务一体化开发引擎 业内独创一体化开发引 ...

  3. 【Codeforces 258A】 Game With Sticks

    [题目链接] http://codeforces.com/contest/451/problem/A [算法] 若n和m中的最小值是奇数,则先手胜,否则后手胜 [代码] #include<bit ...

  4. EOJ 3348 树的顺序存储结构

    前面介绍了树的链式存储结构,那么如何用顺序存储来存储一棵树呢?在顺序存储时,我们除了存储每个结点值外,还要存储树中结点与结点之间的逻辑关系(即双亲与孩子结点之间的关系).下面介绍树的双亲存储法. 编号 ...

  5. 纯JS监听document是否加载完成

    欢迎加入前端交流群交流知识&&获取视频资料:749539640 概述 一个document 的 Document.readyState 属性描述了文档的加载状态. 一个文档的 read ...

  6. css浮动导致的高度塌陷问题及清楚浮动的方法

    浮动很好用,但是用浮动后,当浮动元素的父级元素没有高度时,就会造成高度塌陷,从而影响布局.下面就从一开接触前端时,渐渐发现解决高度塌陷的问题的方式. 一.给浮动元素的父级元素添加固定的高度css[he ...

  7. [Codeforces]Educational Codeforces Round 37 (Rated for Div. 2)

    Water The Garden #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h ...

  8. mysql和eclipse连接jdbc驱动配置

    环境Windows10 eclipse 64位 MySQL 一:资料准备 (MySQL,eclipse下载安装不在赘述) 配置好MySQL环境后 下载jdbc地址http://dev.mysql.co ...

  9. MemCached总结三:PHP的memcached管理接口

    在Web系统中应用MemCached缓存技术,必须使用客户端API(PHP)进行访问,这样才能将用户请求的动态数据,缓存到memcached服务器中,来减少对数据库的访问压力.PHP中提供了用于内存缓 ...

  10. ACM___数学___九的余数

    九的余数 时间限制:3000 ms  |            内存限制:65535 KB 难度:3   描述  现在给你一个自然数n,它的位数小于等于一百万,现在你要做的就是求出这个数整除九之后的余 ...