Codeforces Round #374 (Div. 2) C. Journey —— DP
题目链接:http://codeforces.com/contest/721/problem/C
3 seconds
256 megabytes
standard input
standard output
Recently Irina arrived to one of the most famous cities of Berland — the Berlatov city. There are n showplaces in the city, numbered from 1 to n, and some of them are connected by one-directional roads. The roads in Berlatov are designed in a way such that there are no cyclic routes between showplaces.
Initially Irina stands at the showplace 1, and the endpoint of her journey is the showplace n. Naturally, Irina wants to visit as much showplaces as she can during her journey. However, Irina's stay in Berlatov is limited and she can't be there for more than T time units.
Help Irina determine how many showplaces she may visit during her journey from showplace 1 to showplace n within a time not exceeding T. It is guaranteed that there is at least one route from showplace 1 to showplace n such that Irina will spend no more than Ttime units passing it.
The first line of the input contains three integers n, m and T (2 ≤ n ≤ 5000, 1 ≤ m ≤ 5000, 1 ≤ T ≤ 109) — the number of showplaces, the number of roads between them and the time of Irina's stay in Berlatov respectively.
The next m lines describes roads in Berlatov. i-th of them contains 3 integers ui, vi, ti (1 ≤ ui, vi ≤ n, ui ≠ vi, 1 ≤ ti ≤ 109), meaning that there is a road starting from showplace ui and leading to showplace vi, and Irina spends ti time units to pass it. It is guaranteed that the roads do not form cyclic routes.
It is guaranteed, that there is at most one road between each pair of showplaces.
Print the single integer k (2 ≤ k ≤ n) — the maximum number of showplaces that Irina can visit during her journey from showplace 1 to showplace n within time not exceeding T, in the first line.
Print k distinct integers in the second line — indices of showplaces that Irina will visit on her route, in the order of encountering them.
If there are multiple answers, print any of them.
4 3 13
1 2 5
2 3 7
2 4 8
3
1 2 4
6 6 7
1 2 2
1 3 3
3 6 3
2 4 2
4 6 2
6 5 1
4
1 2 4 6
5 5 6
1 3 3
3 5 3
1 2 2
2 4 3
4 5 2
3
1 3 5
题意:
有n个点, 给出m条边,每条边都有权值(可以理解为距离)。问在T距离之内,从顶点1走到顶点n,最多可以经过多少个顶点?
其中,构成的图中不会出现环,且题目至少有一个答案。
题解:
一开始以为是最短路径,很显然不是,因为题目求的不是最短路,而是在限定的起点、终点和距离的情况下,最多能经过多少个点。
然后想到应该可以用DP:
dp[len][v]:从顶点1开始,途经len个顶点(包括起点终点),终点为v所花费的最短距离。
枚举len*枚举边:在已有的dp[len-1][u]的基础上,再得出dp[len][v], 很有DP的味道。
(注:用vector存顶点之间的关系时,枚举边 = 枚举起点*枚举终点)
保存路径:
一开始是用1维数组fa[]来保存。后来发现,假设当前顶点为v,用一维存的话,存的fa[v]仅仅是路径所能达到最大时的fa[v],而之前长度较小的路径的fa[v]会被新的fa[v]给覆盖掉。因此需要开二维数组fa[len][v]:记录在路径长度为len时,v的前一个顶点。
注意点:
if(dp[len-1][u]==INF) continue; 因为当dp[len-1][u]不合法时(其值设为2e9), 如果直接把他与w(最大为1e9)相加, 结果为3e9,超出了int的范围了。所以以后还是先判断其值是否合法或存在,然后再进项操作。
类似的DP:http://blog.csdn.net/dolfamingo/article/details/71024194
1.枚举长度*枚举起点*枚举终点:
#include <bits/stdc++.h>
using namespace std;
#define ms(a, b) memset((a), (b), sizeof(a))
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; struct node
{
int v, w;
}; int n,m,T;
vector<node>G[maxn];
int dp[maxn][maxn], fa[maxn][maxn]; void init()
{
scanf("%d%d%d",&n,&m,&T); for(int i = ; i<=n; i++)
G[i].clear(); for(int i = ; i<=m; i++)
{
int u;
node e;
scanf("%d%d%d",&u,&e.v,&e.w);
G[u].push_back(e);
} ms(fa,);
for(int i = ; i<=n; i++)
for(int j = ; j<=n; j++)
dp[i][j] = INF;
dp[][] = ;
} void prt(int len, int u)
{
if(len>)
prt(len-, fa[len][u]); printf("%d ",u);
} void solve()
{
int k;
for(int len = ; len<=n; len++)
{
for(int u = ; u<n; u++)
{
for(int i = ; i<G[u].size(); i++)
{
int v = G[u][i].v;
int w = G[u][i].w; if(dp[len-][u]==INF) continue; //少了这步,如果继续用int,会溢出,因为INF+1e9 int tmp = dp[len-][u] + w;
if(tmp<=T && dp[len][v]>tmp)
{
dp[len][v] = tmp;
fa[len][v] = u;
}
}
}
if(dp[len][n]!=INF)
k = len;
} printf("%d\n",k);
prt(k,n); putchar('\n'); } int main()
{
init();
solve();
return ;
}
2.枚举长度*枚举边:
#include <bits/stdc++.h>
using namespace std;
#define ms(a, b) memset((a), (b), sizeof(a))
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; struct node
{
int u, v, w;
void read()
{
scanf("%d %d %d",&u, &v, &w);
}
}edge[maxn]; int n,m,T;
int dp[maxn][maxn], fa[maxn][maxn]; void init()
{
scanf("%d%d%d",&n,&m,&T);
for(int i = ; i<=m; i++)
edge[i].read(); ms(fa,);
for(int i = ; i<=n; i++)
for(int j = ; j<=n; j++)
dp[i][j] = INF;
dp[][] = ;
} void prt(int len, int u)
{
if(len>)
prt(len-, fa[len][u]); printf("%d ",u);
} void solve()
{
int k;
for(int len = ; len<=n; len++)
{
for(int i = ; i<=m; i++)
{
int u = edge[i].u;
int v = edge[i].v;
int w = edge[i].w; if(dp[len-][u]==INF) continue; //少了这步,如果继续用int,会溢出,因为INF+1e9 int cost = dp[len-][u] + w;
if(cost<=T && cost<dp[len][v])
{
dp[len][v] = cost;
fa[len][v] = u;
}
} if(dp[len][n]!=INF)
k = len;
} printf("%d\n",k);
prt(k,n); putchar('\n');
} int main()
{
init();
solve();
return ;
}
Codeforces Round #374 (Div. 2) C. Journey —— DP的更多相关文章
- Codeforces Round #374 (Div. 2) C. Journey DP
C. Journey 题目连接: http://codeforces.com/contest/721/problem/C Description Recently Irina arrived to o ...
- 【Codeforces】Codeforces Round #374 (Div. 2) -- C. Journey (DP)
C. Journey time limit per test3 seconds memory limit per test256 megabytes inputstandard input outpu ...
- CF #374 (Div. 2) C. Journey dp
1.CF #374 (Div. 2) C. Journey 2.总结:好题,这一道题,WA,MLE,TLE,RE,各种姿势都来了一遍.. 3.题意:有向无环图,找出第1个点到第n个点的一条路径 ...
- Codeforces Round #374 (Div. 2) A B C D 水 模拟 dp+dfs 优先队列
A. One-dimensional Japanese Crossword time limit per test 1 second memory limit per test 256 megabyt ...
- 拓扑序+dp Codeforces Round #374 (Div. 2) C
http://codeforces.com/contest/721/problem/C 题目大意:给你有向路,每条路都有一个权值t,你从1走到n,最多花费不能超过T,问在T时间内最多能访问多少城市? ...
- Codeforces Round #374 (Div. 2) C(DAG上的DP)
C. Journey time limit per test 3 seconds memory limit per test 256 megabytes input standard input ou ...
- Codeforces Round #374 (Div. 2) A , B , C 水,水,拓扑dp
A. One-dimensional Japanese Crossword time limit per test 1 second memory limit per test 256 megabyt ...
- Codeforces Round #374 (Div. 2) C DAG上dp
C. Journey time limit per test 3 seconds memory limit per test 256 megabytes input standard input ou ...
- Codeforces Round #374 (div.2)遗憾题合集
C.Journey 读错题目了...不是无向图,结果建错图了(喵第4样例是变成无向就会有环的那种图) 并且这题因为要求路径点尽可能多 其实可以规约为限定路径长的拓扑排序,不一定要用最短路做 #prag ...
随机推荐
- Ubuntu 16.04下使用Wine安装Xshell 4和Xftp 4
说明: 1.使用的Wine版本是深度出品(Deepin),已经精简了很多没用的配置,使启动能非常快,占用资源小. 2.由于Xshell 5的C++库无法在这个Wine版本运行,即使升级官方原版的2+版 ...
- 邁向IT專家成功之路的三十則鐵律 鐵律十六:IT人交友之道-單純
元曲知名的作家 白樸,曾在沉醉東風﹒漁夫一文創作中,寫道:「雖無刎頸交,卻有忘機友」.IT人交朋友應首重在單純而非廣泛,因為實際上越複雜的朋友圈,只會為你的工作以及生活帶來許多不必要的麻煩.至於男女朋 ...
- 【js】小数点后保留两位小数
小数点后保留两位小数 dicountPrice.toFixed(2)
- 电话号码 【trie树】
电话号码 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描写叙述 给你一些电话号码,请推断它们是否是一致的,即是否有某个电话是还有一个电话的前缀. 比方: Emerg ...
- dom4j的xpath查找xml的指定节点
递归遍历所有节点http://blog.csdn.net/sidihuo/article/details/47318723 获取Document SAXReader saxReader = new S ...
- 自己写的通过ADO操作mysql数据库
#include <iostream> #include <windows.h> #include <atlstr.h> #import "c:\Prog ...
- 【转载】C#扫盲之:带你掌握C#的扩展方法、以及探讨扩展方法的本质、注意事项
1.为什么需要扩展方法 .NET3.5给我们提供了扩展方法的概念,它的功能是在不修改要添加类型的原有结构时,允许你为类或结构添加新方法. 思考:那么究竟为什么需要扩展方法呢,为什么不直接修改原有类型呢 ...
- Ubuntu14下Hadoop开发<2> 编译64位Hadoop2.4
Hadoop官方站点仅仅提供了32位的Hadoop包.我装的是64位的系统.自然无法使用,会报错误,导致的结果是无法启动hadoop libhadoop.so.1.0.0 which might ha ...
- canvas 星空插件
(function(a){ a.fn.starBg=function(p){ var p=p||{}; var w_w=p&&p.window_width?p.window_width ...
- Tomcat多实例 - 单机
最近在研究Apache+Tomcat+负载均衡/集群的过程中,发现了一篇好的在单机上部署多个tomcat实例的blog. 感受:关于Apache+Tomcat+负载均衡/集群,国内关于这方面的资料是挺 ...