题意:输入测试组数C,输入N(N条路)和M(M个目标),接着输入N条路的起始横坐标S[i]与终止横坐标E[i],还有这条路的危险值W[i],这些路已按E从小到大排了序。接着输入M个目标路,输出走到相应路的最小危险值和。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2851
——>>这个游戏很好玩,这道题也挺好做。从一条路到另一条路,所以把各条路看作点,比一般的图不一样的是,这些点自身就带有权值,接着就直接来个Dijkstra就好。写完的时候,从第二组测试数据开始就不对了,测试发现,若把vector<int> G[maxn]设为全局量又不清空的话,上一组数据就会影响下一组,于是直接把声明放到了主函数内,ac。
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 2000 + 10, INF = 214748364;
int S[maxn], E[maxn], W[maxn], d[maxn];
bool vis[maxn];
int main()
{
int C, N, M, D, i, j;
scanf("%d", &C);
while(C--)
{
vector<int> G[maxn]; //这小心
scanf("%d%d", &N, &M);
for(i = 1; i <= N; i++) scanf("%d%d%d", &S[i], &E[i], &W[i]);
for(i = 1; i <= N; i++)
for(j = i+1; j <= N; j++)
if(E[i] >= S[j]) G[i].push_back(j);
d[1] = W[1];
memset(vis, 0, sizeof(vis));
for(i = 2; i <= N; i++) d[i] = INF;
for(i = 1; i <= N; i++)
{
int x, m = INF;
for(j = 1; j <= N; j++) if(!vis[j] && d[j] < m) m = d[x=j];
vis[x] = 1;
for(j = 0; j < (int)G[x].size(); j++) d[G[x][j]] = min(d[G[x][j]], m+W[G[x][j]]);
}
while(M--)
{
scanf("%d", &D);
printf("%d\n", (d[D] == INF) ? -1 : d[D]);
}
}
return 0;
}