poj2112 最大流
我用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 最大流的更多相关文章
- poj2112 最大流+floyd+二分
题意:给一堆点,一部分是牛,一部分是机器,每头牛必须要走到一个机器,每个点之间有距离,要求每头牛都能找得到一台机器(机器有最大容量)的情况下,走的最远的牛距离最小 题解:二分答案,小于该距离的边才能加 ...
- POJ2112 Optimal Milking —— 二分图多重匹配/最大流 + 二分
题目链接:https://vjudge.net/problem/POJ-2112 Optimal Milking Time Limit: 2000MS Memory Limit: 30000K T ...
- POJ-2112 Optimal Milking(floyd+最大流+二分)
题目大意: 有k个挤奶器,在牧场里有c头奶牛,每个挤奶器可以满足m个奶牛,奶牛和挤奶器都可以看成是实体,现在给出两个实体之间的距离,如果没有路径相连,则为0,现在问你在所有方案里面,这c头奶牛需要走的 ...
- POJ2112 Optimal Milking 【最大流+二分】
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 12482 Accepted: 4508 ...
- poj2112 二分最大流+Floyd
题意: 一个农场主有一些奶牛,和一些机器,每台机器有自己的服务上限,就是一天最多能给多少头奶牛挤奶,给你任意两点的距离,问你让所有的奶牛都被挤奶时,奶牛于机器最远距离的最近是多少. 思路: ...
- POJ2112 Optimal Milking(最大流)
先Floyd求牛到机器最短距离,然后二分枚举最长的边. #include<cstdio> #include<cstring> #include<queue> #in ...
- poj2112(网络流-最大流+二分)
题意:给你k个挤奶器,c头牛,每个挤奶器能放m头牛,问你奶牛需要走的最大距离最小是多少: 解题思路:因为最大距离最小,也就是求最小的距离满足所有牛都能到,所以我们先用floyd跑最短路,把所有点之间的 ...
- poj2112 二分+floyd+多源多汇最大流
/*此题不错,大致题意:c头牛去k个机器处喝奶,每个喝奶处最多容纳M头牛,求所有牛中走的最长路的 那头牛,使该最长路最小.思路:最大最小问题,第一灵感:二分答案check之.对于使最长路最短, 用fo ...
- [Poj2112][USACO2003 US OPEN] Optimal Milking [网络流,最大流][Dinic+当前弧优化]
题意:有K个挤奶机编号1~K,有C只奶牛编号(K+1)~(C+K),每个挤奶机之多能挤M头牛,现在让奶牛走到挤奶机处,求奶牛所走的最长的一条边至少是多少. 题解:从起点向挤奶机连边,容量为M,从挤奶机 ...
随机推荐
- react高阶函数组件
Layout as a Higher Order Component // components/MyLayout.js import Header from './Header'; const la ...
- VS2013 IIS Express8.0
1.下载最新版本的 Microsoft Web Platform Installer 5.0. 2.在组件列表中选择最新版本的 WebMatrix 3.0,安装重启后即可正常使用 IIS Expres ...
- 手机前端开发调试利器-vConsole
最近因为做抽奖页面,在android上可以使用手机连上电脑后用chrome浏览器chrome://inspect进行页面探测,但是ios中的页面就不能这样探测 在网上搜索后发现此插件,大大解决了问题 ...
- web前端学习(四)JavaScript学习笔记部分(8)-- JavaScript瀑布流
index.html <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type&qu ...
- 纪念——代码首次达到近50K(更新:78.8K 2019行)
#include<bits/stdc++.h> #define re register #define F(A) for(re int (A)=1;(A)<=8;++(A)) usi ...
- 分布式事务 XA 两段式事务 X/open CAP BASE 一次分清
分布式事务: 分布式事务是处理多节点上 的数据保持 类似传统 ACID 事物特性的 一种事物. XA:是一种协议,一种分布式事务的协议,核心思想是2段式提交. 1 准备阶段 2 提交阶段.XA协议是 ...
- idea中使用本地jar包
一个maven项目中使用到了taobao-sdk-java-auto_1455552377940-20160422.jar包,项目是直接导入的jar包而没用用maven的形式导入,导致在idea编辑时 ...
- 使用Pycharm写一个网络爬虫
在初步了解网络爬虫之后,我们接下来就要动手运用Python来爬取网页了. 我们知道,网络爬虫应用一般分为两个步骤: 1.通过网页链接获取内容: 2.对获得的网页内容进行处理 这两个步骤需要分别使用不同 ...
- Docker Nginx部署
1.下载nginx镜像 docker pull nginx 2.创建nginx配置文件 vim /etc/nginx/nginx.conf user nginx; worker_processes 1 ...
- linux系统服务
系统服务分类,根据其使用的方法来分,可以被分为三类 a.由init控制的服务:基本都是系统级别的服务,运行级别这一章讲的就是这一类的服务 b.由System V启动脚本启动的服务:和我们打交道最多的一 ...