我用Dinic写的。G++ 1800ms 很慢,c++直接超时。优化后的 141ms,很快!

对于此题,建图方法很巧妙,通常想到求距离,那就会朝距离的方向建图,但是这题根据牛个数来建图,然后二分距离。

  先求出任意点之间的最短距离。对于挤奶器,牛,很明显的分为2部分。挤奶器的牛来自牛这部分。先另外设源点和汇点。对于牛部分,都与源点相连,容量为1。然后二分

距离,对于挤奶器和牛之间的容量,如果挤奶器和牛之间的距离小于或等于二分的距离,那么此路可以通过牛。然后挤奶器与汇点之间的容量为m值。这样图就建完了。然后Dinic

求最大流(此时最大流的值表示牛的个数),如果此时最大流的值>=c,即满足牛的个数,那这个距离是可以的,然后继续二分,知道得到结果。

#include<stdio.h>
#include<string.h>
#include<queue>
#define maxn 300
#define INF 99999999
using namespace std;
int map[maxn][maxn],dis[maxn][maxn],vis[maxn];
int k,c,m;
int min(int x,int y)
{
return x<y?x:y;
}
void floyd(int n)
{
int i,j,t;
for(t=;t<=n;t++)
{
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
if(dis[i][j]>dis[i][t]+dis[t][j])
dis[i][j]=dis[i][t]+dis[t][j];
}
}
}
}
void makemap(int maxval,int n)
{
int i,j;
memset(map,,sizeof(map));
for(i=;i<=k;i++)
map[i][n+]=m;
for(i=k+;i<=n;i++)
map[][i]=;
for(i=k+;i<=n;i++)
{
for(j=;j<=k;j++)
{
if(dis[i][j]<=maxval)
map[i][j]=;
}
}
}
int BFS(int n)
{
int i,j;
queue<int>q;
memset(vis,-,sizeof(vis));
vis[]=;
q.push();
while(!q.empty())
{
int t=q.front();
q.pop();
for(i=;i<=n+;i++)
{
if(vis[i]<&&map[t][i])
{
q.push(i);
vis[i]=vis[t]+;
}
}
}
if(vis[n+]>)
return ;
return ;
}
int dfs(int u,int low,int n)
{
int i,j,a;
if(u==n)
return low;
for(i=;i<=n;i++)
{
if(vis[i]==vis[u]+&&map[u][i])
{
a=dfs(i,min(low,map[u][i]),n);
if(!a)continue;
map[u][i]-=a;
map[i][u]+=a;
return a;
}
}
return ;
}
int main()
{
int i,j,n;
while(scanf("%d%d%d",&k,&c,&m)!=EOF)
{
n=k+c;
for(i=;i<=k+c;i++)
{
for(j=;j<=k+c;j++)
{
scanf("%d",&dis[i][j]);
if(dis[i][j]==)//不连通给予无穷,防止floyd出现问题
dis[i][j]=INF;
}
}
floyd(n); /*for(i=1;i<=k+c;i++)
{
for(j=1;j<=k+c;j++)
{
printf("%d ",dis[i][j]);
}
printf("\n");
}*/ int L=,R=;
int ans=;
int rt=;
while(L<=R)//二分答案
{
rt=;
int mid=(L+R)/;
makemap(mid,n);//根据二分的值建图
while(BFS(n))
{
int fa=dfs(,INF,n+);
if(!fa) break;;
rt+=fa;
}
if(rt>=c)
{
R=mid-;
ans=mid;
}
else
{
L=mid+;
}
}
printf("%d\n",ans);
}
}

优化后:

#include<stdio.h>
#include<string.h>
#include<queue>
#define maxn 300
#define INF 99999999
using namespace std;
int map[maxn][maxn],dis[maxn][maxn],vis[maxn];
int k,c,m;
int min(int x,int y)
{
return x<y?x:y;
}
void floyd(int n)
{
int i,j,t;
for(t=;t<=n;t++)
{
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
if(dis[i][j]>dis[i][t]+dis[t][j])
dis[i][j]=dis[i][t]+dis[t][j];
}
}
}
}
void makemap(int maxval,int n)
{
int i,j;
memset(map,,sizeof(map));
for(i=;i<=k;i++)
map[i][n+]=m;
for(i=k+;i<=n;i++)
map[][i]=;
for(i=k+;i<=n;i++)
{
for(j=;j<=k;j++)
{
if(dis[i][j]<=maxval)
map[i][j]=;
}
}
}
int BFS(int n)
{
int i,j;
queue<int>q;
memset(vis,-,sizeof(vis));
vis[]=;
q.push();
while(!q.empty())
{
int t=q.front();
q.pop();
for(i=;i<=n+;i++)
{
if(vis[i]<&&map[t][i])
{
q.push(i);
vis[i]=vis[t]+;
}
}
}
if(vis[n+]>)
return ;
return ;
}
int dfs(int u,int low,int n)
{
int i,j,a,used=;
if(u==n)
return low;
for(i=;i<=n&&used<low;i++)
{
if(vis[i]==vis[u]+&&map[u][i])
{
a=dfs(i,min(low-used,map[u][i]),n);//多路增广
if(!a)continue;
map[u][i]-=a;
map[i][u]+=a;
used+=a;
}
}
if(!used)
vis[u]=-;
return used;
}
int main()
{
int i,j,n;
while(scanf("%d%d%d",&k,&c,&m)!=EOF)
{
n=k+c;
for(i=;i<=k+c;i++)
{
for(j=;j<=k+c;j++)
{
scanf("%d",&dis[i][j]);
if(dis[i][j]==)//不连通给予无穷,防止floyd出现问题
dis[i][j]=INF;
}
}
floyd(n); /*for(i=1;i<=k+c;i++)
{
for(j=1;j<=k+c;j++)
{
printf("%d ",dis[i][j]);
}
printf("\n");
}*/ int L=,R=;
int ans=;
int rt=;
while(L<=R)//二分答案
{
rt=;
int mid=(L+R)/;
makemap(mid,n);//根据二分的值建图
while(BFS(n))
{
int fa=dfs(,INF,n+);
if(!fa) break;;
rt+=fa;
}
if(rt>=c)
{
R=mid-;
ans=mid;
}
else
{
L=mid+;
}
}
printf("%d\n",ans);
}
}

poj2112 最大流的更多相关文章

  1. poj2112 最大流+floyd+二分

    题意:给一堆点,一部分是牛,一部分是机器,每头牛必须要走到一个机器,每个点之间有距离,要求每头牛都能找得到一台机器(机器有最大容量)的情况下,走的最远的牛距离最小 题解:二分答案,小于该距离的边才能加 ...

  2. POJ2112 Optimal Milking —— 二分图多重匹配/最大流 + 二分

    题目链接:https://vjudge.net/problem/POJ-2112 Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K T ...

  3. POJ-2112 Optimal Milking(floyd+最大流+二分)

    题目大意: 有k个挤奶器,在牧场里有c头奶牛,每个挤奶器可以满足m个奶牛,奶牛和挤奶器都可以看成是实体,现在给出两个实体之间的距离,如果没有路径相连,则为0,现在问你在所有方案里面,这c头奶牛需要走的 ...

  4. POJ2112 Optimal Milking 【最大流+二分】

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12482   Accepted: 4508 ...

  5. poj2112 二分最大流+Floyd

    题意:      一个农场主有一些奶牛,和一些机器,每台机器有自己的服务上限,就是一天最多能给多少头奶牛挤奶,给你任意两点的距离,问你让所有的奶牛都被挤奶时,奶牛于机器最远距离的最近是多少. 思路: ...

  6. POJ2112 Optimal Milking(最大流)

    先Floyd求牛到机器最短距离,然后二分枚举最长的边. #include<cstdio> #include<cstring> #include<queue> #in ...

  7. poj2112(网络流-最大流+二分)

    题意:给你k个挤奶器,c头牛,每个挤奶器能放m头牛,问你奶牛需要走的最大距离最小是多少: 解题思路:因为最大距离最小,也就是求最小的距离满足所有牛都能到,所以我们先用floyd跑最短路,把所有点之间的 ...

  8. poj2112 二分+floyd+多源多汇最大流

    /*此题不错,大致题意:c头牛去k个机器处喝奶,每个喝奶处最多容纳M头牛,求所有牛中走的最长路的 那头牛,使该最长路最小.思路:最大最小问题,第一灵感:二分答案check之.对于使最长路最短, 用fo ...

  9. [Poj2112][USACO2003 US OPEN] Optimal Milking [网络流,最大流][Dinic+当前弧优化]

    题意:有K个挤奶机编号1~K,有C只奶牛编号(K+1)~(C+K),每个挤奶机之多能挤M头牛,现在让奶牛走到挤奶机处,求奶牛所走的最长的一条边至少是多少. 题解:从起点向挤奶机连边,容量为M,从挤奶机 ...

随机推荐

  1. Eureka 客户端连接Eureka服务端时 报Cannot execute request on any known server 解决办法

    报Cannot execute request on any known server 这个错,总的来说就是连接Eureka服务端地址不对. 因为配置eureka.client.serviceUrl. ...

  2. BigDecimal的四则运算及小数位数格式

    一.加法 BigDecimal b1 = new BigDecimal("20");BigDecimal b2 = new BigDecimal("30");B ...

  3. web前端学习(四)JavaScript学习笔记部分(8)-- JavaScript 浏览器对象

    1.window对象 1.1.window对象: window对象是BOM的核心,window对象指当前的浏览器窗口 所有javaScript全局对象.函数以及变量均自动生成为window对象的成员 ...

  4. 读书笔记--Head First PMP目录

    1.引言 2.阻止.约束和项目 3.过程框架 4.项目整合管理 5.范围管理 6.时间管理 7.成本管理 8.质量管理 9.人力资源管理 10.沟通管理 11.项目风险管理 12.采购管理 13.职业 ...

  5. Constructing Roads POJ - 2421 (最小生成树)

    思路:首先使用二维数组dis[][]处理输入, 对于已经修好的路,将其对应的dis[i][j]置为零即可.最后再将    所有的dis[][]保存到边结构体中,使用Kruskal算法求得最小生成树. ...

  6. 学习Python笔记---操作列表

    1.for循环: 编写for循环时,对于用语存储列表中每个值的临时变量,可指定任何名称. 在for循环中,想包含多少行代码都可以,每个缩进的代码行都是循环的一部分,且将针对列表中的每个值都执行一次. ...

  7. 基于HHT和RBF神经网络的故障检测——第二篇论文读后感

    故障诊断主要包括三部分: 1.故障信号检测方法(定子电流信号检测 [ 定子电流幅值和电流频谱 ] ,振动信号检测,温度信号检测,磁通检测法,绝缘检测法,噪声检测法) 2.故障信号的处理方法,即故障特征 ...

  8. 【AHOI2013复仇】从一道题来看DFS及其优化的一般步骤和数组分层问题【转】

    http://www.cppblog.com/MatoNo1/archive/2012/09/23/191708.html —————————————————————————————————————— ...

  9. docker-4-Dockerfile配置文件详解

    ​ Dockerfile简单一点就是描述你这个镜像安装了哪些软件包,有哪些操作,创建了什么东西.有些人喜欢用 docker commit 命令去打包镜像,这样是不好的,首先commit出来的镜像比你使 ...

  10. 【纯手工】整理豆瓣热点推荐列表-财经&自我管理

    [纯手工]整理豆瓣热点推荐列表-财经&自我管理  简七君 2013-10-27 09:40:06     豆瓣君的首页热点推荐实在难以捉摸,只有正好跳出推荐贴时才能按图索骥找列表.简七和小伙伴 ...