题目链接:here~~
动态规划做的
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <map>
#define FLAG 0
using namespace std;
int p[10010], b[105];//p数组用来存放到达编号为i的点的最小距离,b用来接收当前层的编号
int main()
{
#if(FLAG)
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
int n, m, N, M, i, x, y, z, min, j, w;
while(~scanf("%d%d", &n, &m))
{
memset(p, -1, sizeof(p));
p[0]=0;
for (i = 1; i<=m; i++)
{
scanf("%d%d", &N, &M);
for (j = 1; j<=N; j++)
cin>>b[j];
for (j = 1; j<=M; j++)
{
scanf("%d%d%d", &x, &y, &w);
if (w<=0||p[x]==-1)
continue;
if (p[y]<0||p[y]>w+p[x])//求到达编号为y的点的最小距离
p[y]=p[x]+w;
}
min=(1<<30);
for (j = 1; j<=N; j++)
{
if (p[b[j]]==-1)//如果到达倒数第二层的路<=0,跳过
continue;
if (p[b[j]]<min)
min=p[b[j]];
}
if (min==(1<<30))//如果到达倒数第二层的路都<=0,输出-1
printf("-1\n");
else
printf("%d\n", min+1);
}
min=(1<<30);
for (j = 1; j<=N; j++)
{
if (p[b[j]]==-1)
continue;
if (p[b[j]]<min)
min=p[b[j]];
}
if (min==(1<<30))
printf("-1\n");
else
printf("%d\n", min+1);
}
return 0;
}