jzoj小明逛天界【DP】

>Description
偌大的天界有n个景点,如天阶岛、神犇殿等等,这n个景点的编号分别是1、2、3……n,起点编号为1,终点编号为n,且共有t条道路联通这些景点,被道路联通的每对景点可以相互到达。限时参观卡可以让小明刚好有m个单位时间游览天界,在小明的神奇世界观里,游览天界即是从起点出发直接到达终点或经过中间某些景点(每个景点可重复到达)后到达终点。当然,由于时间有限,小明不一定能把天界的所有景点都游览完。
所以,他想知道,他用刚好m个单位时间到达终点,包括起点和终点最多能游览多少个不同或相同景点(即重复游览相同的景点也算入答案)。


>Input
第一行,三个整数n,m,t,意义如题所述
接下来t行,每行三个整数x,y,z,表示景点x到景点y有一条道路,且从景点x到景点y或从景点y到景点x需要z个单位时间,两个景点之间可能会有多条道路。

>Output
一行,一个整数,表示用刚好m个单位时间到达终点最多能游览不同景点个数,若不能用刚好m个单位时间到达终点,则输出-1


>Sample Input
5 12 4
1 2 5
1 4 3
4 2 4
2 5 5

>Sample Output
4


>解题思路
DP解:f[i][j]为用i个单位时间到第j个景点的最多景点浏览数。


>代码

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,t,f[1005][1005];
int x[50005],y[50005],z[50005],s;
int main()
{
    scanf("%d%d%d",&n,&m,&t);
    for(int i=1;i<=t;i++) scanf("%d%d%d",&x[i],&y[i],&z[i]); 
    //第i条路径:x、y为相连的两点,z为花费的时间。
    f[0][1]=1; //设初值
    for(int i=1;i<=m;i++) //i循环m时间
     for(int j=1;j<=t;j++) //j循环t路径
     {
     	if(i-z[j]<0) continue;
     	if(f[i-z[j]][x[j]]!=0) f[i][y[j]]=max(f[i][y[j]],f[i-z[j]][x[j]]+1);
     	//判断是否能从起点过来,+1加一个景点数
     	if(f[i-z[j]][y[j]]!=0) f[i][x[j]]=max(f[i][x[j]],f[i-z[j]][y[j]]+1);
     	//无向图要判断两次
     } 
    if(f[m][n]!=0) printf("%d",f[m][n]);
    else printf("-1");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43010386/article/details/86602316