注意:
(1)无向图
(2)对于救火队员来说,到达某一点的最短时间为所有救火队员到达该点的最小值。
也就是说只要有一个救火队员到达该店就行;
优化:
(学长给的优化方法)
由于救火队员有多个,我们需要求出每个救火队员到达某一点的时间,再求出最小值;但是救火队员只要有一个到达该点即可,所以,可以在救火队员之间加上权值为0的边,这样只需要求出来一个救火队员到达其它点的时间即可。
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int num=1e6+10;
const int num_p=1010;
const LL inf=1e18;
int n,e,s,k;
LL c;
int team[num_p];
struct node
{
int v,next;
LL w;
node (){};
node(int a,LL b)
{
v=a;w=b;
}
bool operator <(const node & s) const
{
return w > s.w;
}
}edge[num];
int head[num],cnt;
void int_i()
{
cnt=0;
memset(head,0,sizeof(head));
return ;
}
void addedge(int a,int b,LL c)
{
edge[++cnt].v=b;
edge[cnt].w=c;
edge[cnt].next=head[a];
head[a]=cnt;
return ;
}
LL dijkstra(int s,int f)
{
LL dis[num_p];
int book[num_p];
for(int i=1;i<=n;i++)
{
dis[i]=inf;
book[i]=0;
}
dis[s]=0;
priority_queue<node>q;
q.push(node(s,0));
while(!q.empty())
{
node x=q.top();q.pop();
if(book[x.v])
continue;
book[x.v]=1;
for(int i=head[x.v];i;i=edge[i].next)
{
int y=edge[i].v;
if(dis[y] > x.w + edge[i].w)
{
dis[y]=x.w + edge[i].w;
q.push(node(y,dis[y]));
}
}
}
LL ans=0;
for(int i=1;i<=n;i++)
{
ans=max(ans,dis[i]);
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int_i();
scanf("%d%d%d%d%lld",&n,&e,&s,&k,&c);
for(int i=1;i<=k;i++)
{
scanf("%d",&team[i]);
}
int u,v;
LL w;
for(int i=1;i<=e;i++)
{
scanf("%d%d%lld",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
LL ans=dijkstra(s,0);
LL ans2=0;
for(int i=1;i<=k;i++)
for(int j=i+1;j<=k;j++)
{
addedge(team[i],team[j],0);
addedge(team[j],team[i],0);
}
ans2=dijkstra(team[1],0);
if(ans <= ans2*c) {
printf("%lld\n",ans);
}
else {
printf("%lld\n",ans2);
}
}
return 0;
}