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

我们其实这样考虑,费用流真正的思想是吧费用作为长度,然后跑最短路,同时保证路上的流量不为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. Visifire For WPF 图表控件 如何免费

    可能用WPF生成过图表的开发人员都知道,WPF虽然本身的绘图能力强大,但如果每种图表都自己去实现一次的话可能工作量就大了, 尤其是在开发时间比较紧的情况下.这时候有必要借助一种专业的图表工具. Vis ...

  2. Amazon EBS的功能更新

    Amazon EBS(Elastic Block Store.简称EBS) 为 Amazon EC2 实例提供块级存储服务.EBS 卷须要通过网络訪问,而且能独立于实例的生命周期而存在.也就是说假如E ...

  3. day38 09-Spring类的完整生命周期及后处理Bean

    可以配置Bean的这个类的初始化和销毁的方法. 如何销毁这个bean?销毁必须得手动地关闭掉容器才行.而且销毁必须是在scope="singleton"下才有效.因为如果你scop ...

  4. python实例 输出字符串和数字

    但有趣的是,在javascript里我们会理想当然的将字符串和数字连接,因为是动态语言嘛.但在Python里有点诡异,如下: #! /usr/bin/python a=2 b="test&q ...

  5. 快速乘O(1)和O(log)

    O(1)快速乘来自骆可强:<论程序底层优化的一些方法与技巧> //O(1)快速乘 inline LL quick_mul(LL x,LL y,LL MOD){ x=x%MOD,y=y%MO ...

  6. HDU3078 Network [2016年6月计划 树上问题05]

    Network Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  7. 【react】react-reading-track

    这是一个很有趣的图书阅读demo 先放github地址:https://github.com/onlyhom/react-reading-track 我觉得这个博主的项目很有意思呢 我们一起看看代码啊 ...

  8. 如何正确的在Android中存储特定应用文件

    原文地址:How to Correctly Store App-Specific Files in Android Christophe Versieux (Waza_be)发表了一篇rant abo ...

  9. MyEclipse优化】-----如何合理设置MyEclipse中的validation选项

    打开eclipse,点击[window]菜单,选择[preferences]选项. 在左侧点击[validation]选项,在右侧可以看到eclipse进行的自动检查都有哪些内容. 将Manual(手 ...

  10. PHP文件载入和载入路径

    一.文件载入 所谓的文件的载入,就是指将需要的目标文件的代码载入到当前的位置上,从某种意义上来说,文件载入也是一种流程控制! 文件载入的主要目的是体现网站的分层设计,因为不同的页面有很多相同的区域(相 ...