这道题非常好,如果没有真正弄懂费用流算法的人,只会套模版的人是肯定做不出来的。

我们其实这样考虑,费用流真正的思想是吧费用作为长度,然后跑最短路,同时保证路上的流量不为0,也就是增广;

跑到终点后,回溯把路上的流量进行修改。一直这样下去直到无法增广。

这道题也是一样,我们把路径长度看成费用,路径限制看成流量限制。

每次增广到终点后,得到的dis[t]代表源点到汇点的路径长度,incf[t]代表的是这条路上的流量限制。

每一次增广成功,我们都会获得一个和之前不同的路径。

这样我们就能够得到所有s-t路径长度,以及长度对应的流量限制。并且他们所有路径都是满足在流量限制条件下的。

然后其实就很简单了,我们知道我们需要运输的人数,同时知道每一条路径对应的路径的路径运输能力和路径长度,那么我们对答案进行二分,也就是对总共用的时间进行二分。

对于所有路径长度是>=总共运输时间的(每次速度为1),也就是说对于当前的时间内,这条路是可以运载一些人到终点的,那么这条路运输的人数其实就是  e[i].flow*(t-e[i].dist+1)

也就是当前道路的流量*(所用的时间-从起点到终点的时间+1),因为当前道路的在前dist-1的时间内,人还在路上,没有抵达,在dist时间以后,人会源源不断的来到。

注意k可能是0,需要先特判k=0,再特判最大流量=0。不然会错。。。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#define LL long long
using namespace std;
const int maxx = 2e5+;
const LL INF = 1e18;
int ver[maxx],head[maxx],Next[maxx];
LL incf[maxx];
LL cost[maxx],edge[maxx];
int v[maxx],pre[maxx];
LL d[maxx];
int tot,cnt,n,m,s,t;
LL ans,k,maxflow;
struct node
{
LL flow;
LL w;
} a[maxx];
void add(int x,int y,LL z,LL c)
{
ver[++tot]=y;
edge[tot]=z;
cost[tot]=c;
Next[tot]=head[x];
head[x]=tot;
ver[++tot]=x;
edge[tot]=;
cost[tot]=-c;
Next[tot]=head[y];
head[y]=tot;
}
bool spfa()
{
queue<int>q;
while(q.size())q.pop();
for (int i=; i<=n+; i++)
{
d[i]=INF;
v[i]=;
}
q.push(s);
d[s]=;
v[s]=;
incf[s]=INF;
while(q.size())
{
int x=q.front();
v[x]=;
q.pop();
for (int i=head[x]; i; i=Next[i])
{
if (!edge[i])
continue;
int y=ver[i];
//cout<<x<<" "<<y<<" "<<edge[i]<<endl;
if(d[y]>d[x]+cost[i])
{
d[y]=d[x]+cost[i];
incf[y]=min(incf[x],edge[i]);
pre[y]=i;
if(!v[y])v[y]=,q.push(y);
}
}
}
if(d[t]==INF)return false;
else return true;
}
void update()
{
int x=t;
cnt++;
a[cnt].w=d[t];
// cout<<t-1<<"---"<<incf[t]<<"--"<<d[t]<<endl;
a[cnt].flow=incf[t];
while(x!=s)
{
int i=pre[x];
edge[i]-=incf[t];
edge[i^]+=incf[t];
x=ver[i^];
// printf("%d-->",x-1);
}
// cout<<endl;
maxflow+=incf[t];
}
bool check(LL x)
{
LL sum=;
for (int i=; i<=cnt; i++)
{
if (a[i].w<=x)
{
sum+=(LL)a[i].flow*(x-a[i].w+);
}
}
return sum>=k;
}
int main()
{
int uu,vv,c;
while(~scanf("%d%d%lld",&n,&m,&k))
{
cnt=;
tot=;
maxflow=;
s=;
t=n;
memset(head,,sizeof(head));
for (int i=; i<=m; i++)
{
scanf("%d%d%d",&uu,&vv,&c);
add(uu+,vv+,c,);
}
while(spfa())update();
if (k==)
{
printf("0\n");
}
else if (maxflow==){
printf("No solution\n");
}else {
int l=,r=1e9;
while(l<=r)
{
int mid=(l+r)>>;
if (check(mid))
{
r=mid-;
ans=mid;
}
else
{
l=mid+;
}
}
printf("%lld\n",ans);
}
}
return ;
}

HDU-4807-Lunch Time(二分+费用流,思维)的更多相关文章

  1. HDU4807 Lunch Time(费用流变种)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4807 Description The campus of Nanjing Universit ...

  2. HDU 5644 King's Pilots 费用流

    King's Pilots 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5644 Description The military parade w ...

  3. HDU 3667 Transportation(网络流之费用流)

    题目地址:HDU 3667 这题的建图真是巧妙...为了保证流量正好达到k.须要让每一次增广到的流量都是1,这就须要把每一条边的流量都是1才行.可是每条边的流量并非1,该怎么办呢.这个时候能够拆边,反 ...

  4. 【进阶——最小费用最大流】hdu 1533 Going Home (费用流)Pacific Northwest 2004

    题意: 给一个n*m的矩阵,其中由k个人和k个房子,给每个人匹配一个不同的房子,要求所有人走过的曼哈顿距离之和最短. 输入: 多组输入数据. 每组输入数据第一行是两个整型n, m,表示矩阵的长和宽. ...

  5. HDU 3488--Tour(KM or 费用流)

    因为每个点只能经过一次 所以考虑拆点 这题有坑,有重边.. KM算法 把一个点拆成入点和出点 入点在X部,出点在Y步. 如果u,v之间有路径,就在X部的u点连接Y部的v点 求完美匹配. 当完美匹配的时 ...

  6. HDU - 5406 CRB and Apple (费用流)

    题意:对于给定的物品,求两个在高度上单调不递增,权值上单调不递减的序列,使二者长度之和最大. 分析:可以用费用流求解,因为要求长度和最大,视作从源点出发的流量为2的费用流,建负权边,每个物品只能取一次 ...

  7. Lunch Time(费用流变型题,以时间为费用)

    Lunch Time http://acm.hdu.edu.cn/showproblem.php?pid=4807 Time Limit: 4000/2000 MS (Java/Others)     ...

  8. BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

    3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 960  Solved: 5 ...

  9. BZOJ-3130 费用流 (听题目胡扯丶裸最大流) 二分判定+最大流+实数精度乱搞

    DCrusher爷喜欢A我做的水题,没办法,只能A他做不动的题了.... 3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec ...

随机推荐

  1. jnhs中国省市县区mysql数据表不带gps坐标

    1.查省 SELECT * FROM china WHERE china.Pid=0 2.查市 SELECT * FROM chinaWHERE china.Pid=330000 3.查区 SELEC ...

  2. Win7x64易语言调试进程无法退出

    这是个历史问题,几乎所有的Win7x64机器上都会碰到这个问题 解决方法: 启动黑月重新编译器

  3. 阿里云出手SaaS生态,中国SaaS市场小而不强有望破解

    企业服务SaaS市场还有很大的增长空间.SaaS的鼻祖Salesforces今年5月迈上了千亿美元市值的门槛,再一次为ToB市场注入了兴奋剂.单单一个SaaS CRM,目前全球的市场规模就超过400亿 ...

  4. iOS项目转移到自动引用计数

    这里主要参考了Apple官方文档:Transitioning to ARC Release Notes 在支持iOS5的Xcode4中,创建项目会看到这样的选项: 这是iOS5的新特性,自动对象引用计 ...

  5. 从0开始学习 GitHub 系列之「08.如何发现优秀的开源项目」

    之前发过一系列有关 GitHub 的文章,有同学问了,GitHub 我大概了解了,Git 也差不多会使用了,但是 还是搞不清 GitHub 如何帮助我的工作,怎么提升我的工作效率? 问到点子上了,Gi ...

  6. spring拦截器Interceptor

    在Spring Boot中,拦截器可以分为两种类型: 一是WebMVC,负责拦截请求,类似于过滤器,对用户的请求在Controller接收前进行处理,在Controller处理完成后加工结果等.使用时 ...

  7. Http响应response(文件下载、验证码)

    Http响应response response:响应 作用: 往浏览器写东西 组成部分: 响应行 响应头 响应体 操作响应行 格式: 协议/版本 状态码 状态码说明 状态码: 1xx:已发送请求 2x ...

  8. small标签

    <small> 标签将旁注 (side comments) 呈现为小型文本. 免责声明.注意事项.法律限制或版权声明的特征通常都是小型文本.小型文本有时也用于新闻来源.许可要求. 对于由 ...

  9. Significance A and B for protein ratios

    实验设计中,一般会做三个生物学重复来确保结果的准确性,尤其在下游分析中.但有时会遇到没有生物学重复,而又需要进行差异分析的情况,这时一般建议考虑foldchange即可,因为根本无法进行T-test等 ...

  10. python中的open函数

    open函数用于文件处理 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 1 文件句柄 = open('文件路径', '模式') 打开文件时,需要指定文件路径和以何等方式打开文件 ...