1570: [JSOI2008]Blue Mary的旅行

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 388  Solved: 212
[Submit][Status][Discuss]

Description

在一段时间之后,网络公司终于有了一定的知名度,也开始收到一些订单,其中最大的一宗来自B市。Blue Mary决定亲自去签下这份订单。为了节省旅行经费,他的某个金融顾问建议只购买U航空公司的机票。U航空公司的所有航班每天都只有一班,并且都是上午出发当天下午到达的,所以他们每人每天只能坐一班飞机。经过调查,他们得到了U航空公司经营的所有航班的详细信息,这包括每一航班的出发地,目的地以及最多能买到的某一天出发的票数。(注意: 对于一个确定的航班,无论是哪一天,他们最多能买到的那一天出发的票数都是相同的。) Blue Mary注意到他们一定可以只乘坐U航空公司的航班就从A市到达B市,但是,由于每一航班能买到的票的数量的限制,他们所有人可能不能在同一天到达B市。所以现在Blue Mary需要你的帮助,设计一个旅行方案使得最后到达B市的人的到达时间最早。

Input

第一行包含3个正整数N,M和T。题目中会出现的所有城市分别编号为1,2,…,N,其中城市A编号一定为1,城市B编号一定为N. U公司一共有M条(单向)航班。而连Blue Mary在内,公司一共有T个人要从A市前往B市。 以下M行,每行包含3个正整数X,Y,Z, 表示U公司的每一条航班的出发地,目的地以及Blue Mary最多能够买到的这一航班某一天出发的票数。(即:无论是哪一天,Blue Mary最多只能买到Z张U航空公司的从城市X出发到城市Y的机票。) 输入保证从一个城市到另一个城市的单向航班最多只有一个。

Output

仅有一行,包含一个正整数,表示最后到达B市的人的最早到达时间。假设他们第一次乘飞机的那一天是第一天。

Sample Input

3 3 5
1 2 1
2 3 5
3 1 4

Sample Output

6

HINT

约定:
2 <= N <= 50
1 <= M <= 2450
1 <= T <= 50
1 <= X,Y <= N
X != Y
1 <= Z <= 50

Source

Solution

一道比较有趣的建图。

自己一开始想到了建图之后,用费用来搞天数,后来发现是不行的。

正解是采用分层建图,枚举天,然后分层建图,即层与层之间相互连边,直到能跑出答案就退出。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
inline int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 100010
#define MAXM 1000100
int N,M,t;
struct EdgeNode{int next,to,cap,old;}edge[MAXM];
int head[MAXN],cnt=;
inline void AddEdge(int u,int v,int w) {cnt++; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].cap=edge[cnt].old=w;}
inline void InsertEdge(int u,int v,int w) {AddEdge(u,v,w); AddEdge(v,u,);}
int h[MAXN],S,T,cur[MAXN];
#define INF 0x7fffffff
inline bool bfs()
{
queue<int>q;
for (int i=S; i<=T; i++) h[i]=-;
h[S]=; q.push(S);
while (!q.empty())
{
int now=q.front(); q.pop();
for (int i=head[now]; i; i=edge[i].next)
if (h[edge[i].to]==- && edge[i].cap)
h[edge[i].to]=h[now]+,q.push(edge[i].to);
}
return h[T]!=-;
}
inline int dfs(int loc,int low)
{
if (loc==T) return low;
int used=,w;
for (int i=cur[loc]; i; i=edge[i].next)
if (edge[i].cap && h[edge[i].to]==h[loc]+)
{
w=dfs(edge[i].to,min(edge[i].cap,low-used));
edge[i].cap-=w; edge[i^].cap+=w; used+=w;
if (used==low) return low;
if (edge[i].to) cur[loc]=i;
}
if (!used) h[loc]=-;
return used;
}
inline int Dinic()
{
int tmp=;
while (bfs())
{
for (int i=S; i<=T; i++) cur[i]=head[i];
tmp+=dfs(S,INF);
}
return tmp;
}
struct eNode{int u,v,c;}e[MAXN];
inline int id(int day,int id) {return day*N+id;}
int main()
{
N=read(),M=read(),t=read();
for (int i=; i<=M; i++) e[i].u=read(),e[i].v=read(),e[i].c=read();
S=,T=(N+t)*N+;
InsertEdge(S,,t);
for (int i=; i<=N+t; i++)
{
for (int j=; j<=cnt; j++) edge[j].cap=edge[j].old;
for (int j=; j<=M; j++) InsertEdge(id(i-,e[j].u),id(i,e[j].v),e[j].c);
for (int j=; j<=N; j++) InsertEdge(id(i-,j),id(i,j),INF);
InsertEdge(id(i,N),T,INF);
int flow=Dinic(); if (flow==t) {printf("%d\n",i); return ;}
}
return ;
}

最新文章

  1. iOS系统分析(二)Mach-O二进制文件解析
  2. jquery基本选择器(.class选择器)
  3. 在脚本中操作plist文件
  4. android 搭建开发环境
  5. Android开发之bug-No Activity found to handle Intent
  6. 解决wordpress上传的文件尺寸超过 php.ini 中定义的 upload_max_filesize 值。
  7. beforefieldinit释义(3)
  8. (11.20)Java小知识!
  9. 如何配置 Health Check?- 每天5分钟玩转 Docker 容器技术(107)
  10. 使用腾讯云“自定义监控”监控GPU使用率
  11. JavaScript中高阶函数
  12. js设置回车键触发事件
  13. 日志切割之Logrotate
  14. laravel安装laravel-ide-helper扩展进行代码提示(二)
  15. Web测试和App测试有什么区别
  16. java程序员一些初中级面试题(数据库部分)
  17. 短信猫+kannel调试一例
  18. 客户端连接linux经常间隔性断开链接【转】
  19. 使用 stretchableImageWithLeftCapWidth 方法实现可伸缩图片
  20. 判断回文字符串(c,python)

热门文章

  1. 设置Hyper V
  2. CSS3-05 样式 4
  3. 开篇:软件项目的整个流程 - IT软件人员学习系列文章
  4. IT人经济思维之创业 - 创业与投资系列文章
  5. asp.net signalR 专题—— 第二篇 对PersistentConnection持久连接的快速讲解
  6. Blog List
  7. memcache+magent的高可用
  8. C++中的也能使用正则表达式
  9. Appium学习实践(五)遇到的坑(记录自己工作中遇到的坑以及解决方案,不定时更新)
  10. HashMap,Hashtable,TreeMapMap