您的位置:首页 > 其它

codeforce 374C. Journey(dp)

2016-10-08 12:04 274 查看
传送门:C. Journey

这是一个典型的图论里的题目,解法和Bellman-Ford算法很类似,题意要求从第一个点开始在规定时间内到达最多的点,而且最后一定要在n点(题目保证在规定时间内能到达n点),用dfs的话会超时,所以应该用dp。

设dp[i][j]表示经过i个点到达j点所用的最小时间,则题意变成在dp[i]
<=t
里找最大的i就好了,外层循环遍历i的可能取值,内层循环遍历所有的边,状态转移方程为:

dp[i][v]=min(dp[i-1][u]+w(u,v)).

初始化的时候将所有点置为t+1就好了,这里t+1和inf的作用是一样的,本题中既然找小于等于t的,那么t+1和t+2和inf就没区别了。

还有就是要输出路径,所以要开辟一个数组father[i][j]来记录j点是经过i个点由father[i][j]到达的,然后最后根据最多能到达的点的个数回溯路径就好了。

#include <iostream>
#include <cstdio>
#include <cstring>
#define M 5005
using namespace std;
int n,m,t,pos;
struct node{
<span style="white-space:pre"> </span>int u,v,w;
}edge[M];
int dp[M][M],father[M][M];
int line[M];
void dpsolve()
{
<span style="white-space:pre"> </span>int u,v,w;
<span style="white-space:pre"> </span>for(int i=2;i<=n;i++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>for(int j=1;j<=m;j++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>u=edge[j].u;
<span style="white-space:pre"> </span>v=edge[j].v;
<span style="white-space:pre"> </span>w=edge[j].w;
<span style="white-space:pre"> </span>if(dp[i][v]>dp[i-1][u]+w)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>dp[i][v]=dp[i-1][u]+w;
<span style="white-space:pre"> </span>father[i][v]=u;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if(dp[i]
<=t)
<span style="white-space:pre"> </span>pos=i;
<span style="white-space:pre"> </span>}
}
int main()
{
<span style="white-space:pre"> </span>scanf("%d%d%d",&n,&m,&t);
<span style="white-space:pre"> </span>for(int i=1;i<=m;i++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>for(int i=0;i<=n;i++)
<span style="white-space:pre"> </span>for(int j=0;j<=n;j++)
<span style="white-space:pre"> </span>dp[i][j]=t+1;
<span style="white-space:pre"> </span>dp[1][1]=0;
<span style="white-space:pre"> </span>dpsolve();
<span style="white-space:pre"> </span>printf("%d\n",pos);
<span style="white-space:pre"> </span>int index=0,tt=n;
<span style="white-space:pre"> </span>for(int j=pos;j>0;j--)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>line[index++]=tt;
<span style="white-space:pre"> </span>tt=father[j][tt];
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>printf("%d",line[index-1]);
<span style="white-space:pre"> </span>for(int j=index-2;j>=0;j--)
<span style="white-space:pre"> </span>printf(" %d",line[j]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp codeforces