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 ...
随机推荐
- Xamarin XAML语言教程对象元素的声明方式
Xamarin XAML语言教程对象元素的声明方式 XAML的对象元素的声明有两种形式,分别为包含属性的特性语法形式以及对象元素语法形式.在1.4小节中,我们看到了其中一种对XAML对象元素的声明方式 ...
- ruti
也许我可以说除了我把+号写成了-号这个程序几乎是完美的
- spring版本不兼容JDK问题
在实验书上Spring项目的时候出现一个问题,导入包和使用注释的时候eclipse出现报错. 导入包报错:The import org cannot be resolved 注释报错:componen ...
- DNA的复制
半保留复制 DNA分子复制时, DNA分子的双螺旋将解开, 互补的碱基之间的氢键断裂, 解开的两条单链作为复制的模板, 游离的脱氧核苷酸依据碱基互补配对的原则, 通过形成氢键结合到作为模板的单链上. ...
- 转:PHP 生成复杂JSON格式 简单快速方法
PHP 生成JSON 格式主要使用json_encode()函数.这个函数的输入参数支持PHP数组和对象类型. 查阅网上的例子通常都是使用数组的,也有个别使用对象生成.但实际项目中,我们要生成的JSO ...
- python--文本处理1
1.字符和字符值之间的转换 内建函数:ord(),chr() >>> print ord("a") 97 >>> print chr(97) a ...
- 精简版的MySQL制作步骤
1.删除所有的目录,只保留 datasharebin 2.删除BIN下面除以下三个文件之外的所有文件: libmysql.dll(MYSQL5中的文件,在MYSQL5.5中不存在)mysqladmin ...
- Direct2D教程(二)来看D2D世界中的Hello,World
引子 任何一门语言的第一个教程几乎都是Hello,world.我们也不例外,但是这里不是教大家打印Hello,world,而是编写一个简单的D2D绘制程序,让大家对Direct2D的程序结构及编程方法 ...
- 机器学习(十三)——机器学习中的矩阵方法(3)病态矩阵、协同过滤的ALS算法(1)
http://antkillerfarm.github.io/ 向量的范数(续) 范数可用符号∥x∥λ表示. 经常使用的有: ∥x∥1=|x1|+⋯+|xn| ∥x∥2=x21+⋯+x2n−−−−−− ...
- Ubuntu 安装 spark
环境: Unbunt 12.04 Hadoop 2.2.x Sprak 0.9 Scala scala-2.9.0.final.tgz 步骤 1. 下载 scala 2. 解压scala,然后改动/e ...