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

我们其实这样考虑,费用流真正的思想是吧费用作为长度,然后跑最短路,同时保证路上的流量不为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. [转]json对象详解

    json(javascript object notation)全称是javascript对象表示法,它是一种数据交换的文本格式,而不是一种编程语言,用于读取结构化数据.2001年由Douglas C ...

  2. day36 10-Hibernate中的事务:解决丢失更新

    演示hibernate如何产生丢失更新的 丢失更新是怎么玩的?首先两个事务先都把它查出来. A事务里面去修改的数据没了,被B事务覆盖掉了.这是被B事务提交覆盖,B事务回滚也能覆盖.这就是丢失更新的效果 ...

  3. HDU - 1724 Ellipse 自适应辛普森模板

    OJ 题解传送门 //Achen #include<algorithm> #include<iostream> #include<cstring> #include ...

  4. python中的True和False

    返回真假时,需要为: return True return False

  5. 【CF Manthan, Codefest 17 A】Tom Riddle's Diary

    [链接]h在这里写链接 [题意] 在这里写题意 [题解] /* Be careful. 二重循环枚举 */ [错的次数] 0 [反思] 在这了写反思 [代码] #include <bits/st ...

  6. IE8下图片无法显示问题

    一.背景图片不能显示的原因 代码: background:url(img/img1.jpg)no-repeat; background:url(img/img1.jpg) no-repeat; 第一个 ...

  7. SQL优化经验总结34条

    SQL优化经验总结34条 我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为笔者学习.摘录.并汇总部分资料与大家分享! (1) 选择最有效率的表名顺序(只在基于规则的优化器中有效): OR ...

  8. Thrift源码分析(一)-- 基本概念

    我所在的公司使用Thrift作为基础通信组件,相当一部分的RPC服务基于Thrift框架.公司的日UV在千万级别,Thrift很好地支持了高并发访问,并且Thrift相对简单地编程模型也提高了服务地开 ...

  9. CSS user-select文本是否可复制

    1. 概述 1.1 说明 在项目过程中,有时候需要网页中内容信息不可被复制进行保护数据信息,故可使用css属性user-select进行控制用户能否选中文本. 1.2 语法 user-select : ...

  10. left join table_a on ...like...