Lunch Time

http://acm.hdu.edu.cn/showproblem.php?pid=4807

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 782    Accepted Submission(s): 183

Problem Description
The campus of Nanjing University of Science and Technology can be viewed as a graph with N vertexes and M directed edges (vertexes are numbered from 0 to N - 1). Each edge has the same length 1. Every day, there are K students walking to the dinning-hall (vertex N - 1) from the teaching building (vertex 0) at lunch time. They all want reach the dinning-hall as soon as possible. However, each edge can only serve at most ci students at any time. Can you make arrangements for students, so that the last student can reach the dinning-hall as soon as possible? (It is assumed that the speed of the students is 1 edge per unit time)
 
Input
There are several test cases, please process till EOF.
The first line of each test case contains three integer N(2 <= N <= 2500), M(0 <= M <= 5000), K(0 <= K <= 109). Then follows M lines, each line has three numbers ai, bi, ci(0 <= ci <= 20), means there is an edge from vertex ai to bi with the capacity ci.
 
Output
For each test case, print an integer represents the minimum time. If the requirements can not be met, print “No solution”(without quotes) instead.
 
Sample Input
5 6 4
0 1 2
0 3 1
1 2 1
2 3 1
1 4 1
3 4 2
3 3 10
0 1 1
1 2 1
0 2 1
2 0 1
 
Sample Output
3
6
No solution
 
Source
 
 
 
 #include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std; const int INF=0x3f3f3f3f;
const int N=;
const int M=;
int top;
int dist[N],pre[N];
bool vis[N];
int c[N];
int maxflow; struct Vertex{
int first;
}V[N];
struct Edge{
int v,next;
int cap,flow,cost;
}E[M]; void init(int n){
for(int i=;i<=n;i++){
V[i].first=-;
}
top=;
maxflow=;
} void add_edge(int u,int v,int c,int cost){
E[top].v=v;
E[top].cap=c;
E[top].flow=;
E[top].cost=cost;
E[top].next=V[u].first;
V[u].first=top++;
} void add(int u,int v,int c,int cost){
add_edge(u,v,c,cost);
add_edge(v,u,,-cost);
} bool SPFA(int s,int t,int n){
int i,u,v;
queue<int>qu;
for(i=;i<=n;i++){
dist[i]=INF;
vis[i]=false;
c[i]=;
pre[i]=-;
}
vis[s]=true;
c[s]++;
dist[s]=;
qu.push(s);
while(!qu.empty()){
u=qu.front();
qu.pop();
vis[u]=false;
for(i=V[u].first;~i;i=E[i].next){
v=E[i].v;
if(E[i].cap>E[i].flow&&dist[v]>dist[u]+E[i].cost){
dist[v]=dist[u]+E[i].cost;
pre[v]=i;
if(!vis[v]){
c[v]++;
qu.push(v);
vis[v]=true;
if(c[v]>n){
return false;
}
}
}
}
}
if(dist[t]==INF){
return false;
}
return true;
} int MCMF(int s,int t,int n,int k){
if(k==) return ;////////////*******************////
int d;
int i,mincost;
mincost=;
int ans=INF;
int sum_peo=k,now_peo=,list_time=;
while(SPFA(s,t,n)){
d=INF;
for(i=pre[t];~i;i=pre[E[i^].v]){
d=min(d,E[i].cap-E[i].flow);
}
maxflow+=d;
for(i=pre[t];~i;i=pre[E[i^].v]){
E[i].flow+=d;
E[i^].flow-=d;
}
mincost+=dist[t]*d;
sum_peo-=(dist[t]-list_time)*now_peo+d;
list_time=dist[t],now_peo+=d;
int now=dist[t]+(int)ceil((1.0*(sum_peo<?:sum_peo))/now_peo);
if(ans>now) ans=now;
if(sum_peo<) break;
}
return ans;
} int main(){
int n,m,k;
int v,u,w,c;
int s,t;
while(~scanf("%d %d %d",&n,&m,&k)){
s=,t=n-;
init(n);
for(int i=;i<=m;i++){
scanf("%d %d %d",&v,&u,&c);
add(v,u,c,);
}
int ans=MCMF(s,t,n,k);
if(ans==INF) printf("No solution\n");
else printf("%d\n",ans);
}
}
/*
题意:
    给你一个有向图,每条边上都有每一时刻的最大流量,有k个人在点0,
他们要去点n-1,问你最晚到达的那个人最快要多久。
思路:
    这道题目用该是借助费用流的找新路径去枚举,可以说是费用流变形吧,
首先我们一定要明白一点,就是时间的影响,单纯的最大流如果在时间的基础上考虑没什么意义,
而费用流呢,我们想象一下,如果把时间设成费用那么我们就可以吧流量和时间结合起来了,
在费用流的过程中我们要知道,他每一次都是根据最短路去找新的路径的,
也就是说路径在费用上来说是递增的(流量不一定),
那么我们就可以根据这个特点来枚举一那些路径来过人,
要明白,如果起点到终点有两条边,一条很近,一条很远,
有可能大家都走近的路径(宁可排队走),也不走远的(所以直接最大流是错了),
那么我们就可以枚举路径了,路径可以直接用费用流每次的路径,因为时间递增的,
对于每一次我们能过的人是多少呢?这个地方很关键,对于每一条路径来说,
如果当前的路径a距离是10,流量是15,那么当时间大于10的时候,每过一个时间单位,路径a都可以再过15个人,
所以当前的时间段的总人数是之前的总人数+(当前长度-上一个长度)* 上一个的总流量 + 当前流量
那么如果现在当前这一部之前的所有路径当路径要花费的时间是多少呢
now = 当前长度+剩余的路径长度/当前总流量  向上取整
这样比较now和ans更新答案就行了,
还有一个地方要明确,就是当总人数超过全图的最大流的时候答案就是
费用流中最长的路径 + 总人数/全图最大流 向上取整,
这个地方不用特判,上面的想法里面包括在这里,说了只是为了便于理解。 */

Lunch Time(费用流变型题,以时间为费用)的更多相关文章

  1. Coding Contest(费用流变形题,double)

    Coding Contest http://acm.hdu.edu.cn/showproblem.php?pid=5988 Time Limit: 2000/1000 MS (Java/Others) ...

  2. POJ 3686 The Windy's(思维+费用流好题)

    The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5362   Accepted: 2249 Descr ...

  3. HDU 3376 &amp;&amp; 2686 方格取数 最大和 费用流裸题

    题意: 1.一个人从[1,1] ->[n,n] ->[1,1] 2.仅仅能走最短路 3.走过的点不能再走 问最大和. 对每一个点拆点限流为1就可以满足3. 费用流流量为2满足1 最大费用流 ...

  4. Going Home POJ - 2195 费用流板子题

    On a grid map there are n little men and n houses. In each unit time, every little man can move one ...

  5. bzoj3442: 学习小组(费用流好题)

    3442: 学习小组 题目:传送门 题解: 超级好题啊大佬们的神题!建图肥肠灵性!感觉自己是星际玩家... 首先呢st直接向每个人连边,容量为min(k,喜欢的小组个数),费用为0 然后每个人再向ed ...

  6. CFGYM 2013-2014 CT S01E03 D题 费用流模版题

    题意: n行, a房间的气球,b房间的气球 i行需要的气球,与a房的距离,b房的距离 求最小距离 #include <stdio.h> #include <string.h> ...

  7. 【BZOJ-2055】80人环游世界 上下界费用流 (无源无汇最小费用最大流)

    2055: 80人环游世界 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 321  Solved: 201[Submit][Status][Discus ...

  8. 费用流+SPFA ||【模板】最小费用最大流

    题面:[模板]最小费用最大流 代码: #include<cstdio> #include<cstring> #include<iostream> #include& ...

  9. 【费用流】【Next Array】费用流模板(spfa版)

    #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using ...

随机推荐

  1. 数组比较大小的几种方法及math是方法

    call apply bind 的区别? 解决函数内this的指向: 1.可以在函数外提前声明变量 一般情况下我们用   var _this/that=this 2.通过apply和call来修改函数 ...

  2. 计算图像相似度——《Python也可以》之一

    声明:本文最初发表于赖勇浩(恋花蝶)的博客http://blog.csdn.net/lanphaday 先将两张图片转化为直方图,图像的相似度计算就转化为直方图的距离计算了,本文依照如下公式进行直方图 ...

  3. 补充2:Golang 一些特性

    Go语言的这些地方都做的还不错: 拥有自动垃圾回收: 不用手动释放内存 一个包系统: Go 语言的源码复用建立在包(package)基础之上.包通过 package, import, GOPATH 操 ...

  4. 【Codeforces】CF 5 C Longest Regular Bracket Sequence(dp)

    题目 传送门:QWQ 分析 洛谷题解里有一位大佬讲的很好. 就是先用栈预处理出可以匹配的左右括号在数组中设为1 其他为0 最后求一下最长连续1的数量. 代码 #include <bits/std ...

  5. 【Unix网络编程】 chapter5 TCP客户,服务器程序实例

    chapter5 5.1 概述 5.2 TCP回射服务器程序:main函数 int main(int argc, char **argv) { int listenfd,connfd; pid_t c ...

  6. php 学习笔记 设计和管理

    代码管理 文件路径.数据库名.密码禁止 hard coded 避免重复代码在多个页面复制粘贴 Gang of Four eXtreme Programming 的主要原则是坚决主张测试是项目成功的关键 ...

  7. json 拖拽

    1.梳理知识点 1.事件对象   e || event  2.事件对象的属性      鼠标事件对象 : 坐标属性 :  clientX  clientY  pageX  pageY   offset ...

  8. Redis-基本数据类型与内部存储结构

    1-概览 Redis是典型的Key-Value类型数据库,Key为字符类型,Value的类型常用的为五种类型:String.Hash .List . Set . Ordered Set 2- Redi ...

  9. 写下thinkphp5和thinkphp3.2的不同

    只列出一些自己的直观感受 1 引入了命令行,估计来源是laravel,前阵子刚练手完laravel5.0的系统, 感觉thinkphp5的命令行和laravel的很像 2 引入了路由,来源估计也是la ...

  10. 1_Utilities__deviceQuery + 1_Utilities__deviceQueryDrv + 1_Utilities__topologyQuery

    使用 Runtime API 和 Driver API 检测设备相关属性.并检测了设备之间的拓扑以及主机与设备之间的拓扑(是否支持跨设备原子操作). ▶ 源代码:Runtime API #includ ...