/*此题不错,大致题意:c头牛去k个机器处喝奶,每个喝奶处最多容纳M头牛,求所有牛中走的最长路的

那头牛,使该最长路最小。思路:最大最小问题,第一灵感:二分答案check之。对于使最长路最短,

用folyd算出所有牛到每个喝奶点的最短路,每次枚举最大值,取不大于该值的路,重新构图;把所有牛赶去

喝奶点,在喝奶点有限制,不是多源多汇吗?!取超级源点,限制为1(一头牛),超级汇点,限制为

m,即可。其他路限制随意。

关键点:分清哪些是流量,最短路只是构图的一个方式(条件)。此题注意编号(原图1--k是目标,后面是

牛(起点)。)

#include<iostream>   //140ms, 1A
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
int k,c,m;const int inf =0x3f3f3f3f;
int a[250][250]; int minmax;
int e[20000][3];int head[250]; //链式前向星二维数组表示法,0:to,1:pre,2:wight;
void folyd() //最短路不用说
{
for(int i=1;i<=k+c;i++)
for(int j=1;j<=k+c;j++)
for(int ii=1;ii<=k+c;ii++)
{
if(a[j][ii]>a[j][i]+a[i][ii])
{
a[j][ii]=a[j][i]+a[i][ii];
if(a[j][ii]>minmax)minmax=a[j][ii]; //枚举上界
}
}
}
void build(int limit) //由限制,选小于之的路,重新构图
{
for(int i=0;i<=k+c+2;i++)
head[i]=-1;
int num=0;
for(int i=c+1;i<=c+k;i++) //超级汇点
{
e[num][0]=c+k+1;e[num][1]=head[i];head[i]=num;
e[num++][2]=m;
e[num][0]=i;e[num][1]=head[c+k+1];head[c+k+1]=num;
e[num++][2]=0;
}
for(int i=1;i<=c;i++) //超级源点
{
e[num][0]=0;e[num][1]=head[i];head[i]=num;
e[num++][2]=0;
e[num][0]=i;e[num][1]=head[0];head[0]=num;
e[num++][2]=1;
}
for(int i=1;i<=k;i++) //其他点
for(int j=k+1;j<=k+c;j++)
if(a[i][j]<=limit)
{
e[num][0]=j-k;e[num][1]=head[i+c];head[i+c]=num;
e[num++][2]=0;
e[num][0]=i+c;e[num][1]=head[j-k];head[j-k]=num;
e[num++][2]=1;
}
}
int level[250];int vis[250];
bool bfs() //bfs+dfs,dinic算法
{
for(int i=0;i<=k+c+1;i++)
vis[i]=level[i]=0;
queue<int>q;
q.push(0);vis[0]=1;
while(!q.empty())
{
int cur=q.front();q.pop();
for(int i=head[cur];i!=-1;i=e[i][1])
{ int to=e[i][0];
if(!vis[to]&&e[i][2]>0)
{
vis[to]=1;
level[to]=level[cur]+1;
if(to==k+c+1)return 1;
q.push(to);
}
}
}
return vis[k+c+1];
}
int dfs(int uu,int minf)
{
if(uu==k+c+1||minf==0)return minf;
int sum=0,f;
for(int i=head[uu];i!=-1&&minf;i=e[i][1])
{ int to=e[i][0];
if(level[to]==level[uu]+1&&e[i][2]>0)
{
f=dfs(to,minf<e[i][2]?minf:e[i][2]);
e[i][2]-=f;e[i^1][2]+=f;
sum+=f;minf-=f;
}
}
return sum;
}
bool check(int limit)
{
build(limit);
int sumflow=0;
while(bfs())
{
sumflow+=dfs(0,inf);
}
if(sumflow==c) //所有牛可以去才是对
return 1;
return 0;
}
int main()
{
scanf("%d%d%d",&k,&c,&m);
for(int i=1;i<=k+c;i++)
for(int j=1;j<=k+c;j++)
{
int temp1;
scanf("%d",&temp1);
if(temp1==0)a[i][j]=inf;
else a[i][j]=temp1;
}
folyd();
int left=0,right=minmax,mid;
while(right>left+1) //二分答案,注意一下
{
mid=(right+left)/2;
if(check(mid))
{
right=mid;
}
else
left=mid;
}
if(check(right-1)) //最后二分时判断特殊情况
printf("%d\n",right-1);
else
printf("%d\n",right); }

最新文章

  1. tomcat/jsp/servlet版本关系
  2. CentOs 6.5 安装Ganglia步骤
  3. C++11引用临时变量的终极解析
  4. 百度云 + GIT
  5. Java的基本程序设计结构(上)
  6. 黑马程序员+SQL基础(下)
  7. 浅析SqlServer简单参数化模式下对sql语句自动参数化处理以及执行计划重用
  8. web框架学习列表
  9. spring 定时器----quartz启动问题
  10. 转:Server.MapPath相关
  11. java_eclipse添加DID实现自动提示
  12. CSS中可以继承和不可继承的常见属性
  13. CSS:margin和padding之谜
  14. 分布式系统消息中间件——RabbitMQ的使用基础篇
  15. Spring Security的核心拦截器
  16. Java知多少(101)图像缓冲技术
  17. LCS(最长公共子序列)问题
  18. tp5闭包子查询传参方法
  19. 8.Generics 泛型(Dart中文文档)
  20. source insight 支持verilog 及使用技巧

热门文章

  1. Linux系统结构与终端控制台
  2. nginx,php-fpm的安装配置
  3. javaee 第14周
  4. 利用MSF实现三层网络的一次内网渗透
  5. upload 上传按钮组件 iview
  6. jquery 定位
  7. spring boot 在idea中实现热部署
  8. 《编译原理》画 DAG 图与求优化后的 4 元式代码- 例题解析
  9. 手动编译openslide
  10. 天梯赛L1 题解