这个题相比较于一般的SPFA,还多加了一步草儿的家与图上的一些点相连,且距离为0。所以我们用链式前向星先来储存不连接图中点与 草儿的家 的边,然后再储存连接图中点与 草儿的家 的边。然后用SPFA来找出每个点到草儿的家的对短距离就OK了。(多亏题目给的点是1到1000,这样就可以把 草儿的家 设为0)
下面是AC代码(因为题目没有考虑负环,所以就没有进行负环的判断):
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 10000;
const int MAX = 0xffffff;
struct stuff{
int to;
int len;
int sign;
}road[maxn];
int id[maxn];
int d[maxn];
int vis[maxn];
int cnt;
void add(int from, int to, int lenth)
{
road[cnt].to = to;
road[cnt].len = lenth;
road[cnt].sign = id[from];
id[from] = cnt++;
}
void spfa()
{
vis[0] = 1;
queue<int> q;
q.push(0);
d[0] = 0;
//cout << "ah" << endl;
while(!q.empty())
{
//cout << "ds" << endl;
int t = q.front();
q.pop();
for(int i = id[t]; i != -1; i = road[i].sign)
{
if(d[road[i].to] > d[t] + road[i].len)
{
d[road[i].to] = d[t] + road[i].len;
//printf("%d->%d is %d\n", t, road[i].to, d[road[i].to]);
if(!vis[road[i].to])
{
vis[road[i].to] = 1;
q.push(road[i].to);
}
}
}
}
}
int main()
{
int T,S,D;
while(scanf("%d%d%d", &T,&S,&D) != EOF)
{
int i, a, b, r;
cnt = 0;
for(i=0; i<maxn; i++)
{
vis[i] = 0;
id[i] = -1;
d[i] = MAX;
}
for(i=0; i<T; i++)
{
scanf("%d%d%d", &a,&b,&r);
add(a,b,r);
add(b,a,r);
}
for(i=0; i<S; i++)
{
scanf("%d", &a);
add(0,a,0);
add(a,0,0);
}
//cout << "haha" << endl;
spfa();
int minn = MAX;
for(i=0; i<D; i++)
{
scanf("%d", &a);
if(d[a] < minn)
minn = d[a];
}
cout << minn << endl;
}
return 0;
}