题意:有一个消防英雄在s点,k个消防点有消防队,问你消防队到任意一点的最短路的最大值与消防英雄到任意一点的最大值*1/c哪个小
题解:注意!A draw is also a victory for fire-fighting hero!即ans1<=ans2*c输出ans1!,
我贴两种办法,一种是并查集缩点建新图,另一种是把ki之间都连上权值为0的边
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mem(s) memset(s, 0, sizeof(s))
const ll INF = 1e18;
const double eps = 1e-8;
const int maxn = 1000+5;
const int mod = 998244353;
int pre[maxn];
int Find(int x){
if(pre[x]==x)return x;
else return pre[x]=Find(pre[x]);
}
void mix(int x,int y){
int fx=Find(x),fy=Find(y);
if(fx!=fy){
pre[fy]=fx;
}
}
struct edge{int to; ll cost;
edge(){}
edge(int v,ll w){to=v;cost=w;}
};
struct{
typedef pair < ll,int> P;
int n,m;
vector<edge>G[maxn*maxn];
ll d[maxn*maxn];
void dijkstra(int s){
priority_queue<P,vector<P>,greater<P> >que;
fill(d,d+n+1,INF);
d[s]=0;
que.push(P(0,s));
while(!que.empty()){
P p=que.top();que.pop();
int v=p.second;
if(d[v]<p.first)continue;
for(int i=0;i<G[v].size();i++){
edge e=G[v][i];
if(d[e.to]>d[v]+e.cost){
d[e.to]=d[v]+e.cost;
que.push(P(d[e.to],e.to));
}
}
}
}
}dij1,dij2;
int v,e,s,k,c;
void init(){
dij1.n=v;dij1.m=e;dij2.n=v;dij2.m=e;
for(int i=0;i<=v;i++)pre[i]=i,dij1.G[i].clear(),dij2.G[i].clear();
}
int ki[maxn],ui[maxn*maxn],vi[maxn*maxn],wi[maxn*maxn];
int32_t main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d%d",&v,&e,&s,&k,&c);
init();
for(int i=1;i<=k;i++)scanf("%d",&ki[i]);
for(int i=1;i<=e;i++){
scanf("%d%d%d",&ui[i],&vi[i],&wi[i]);
dij1.G[ui[i]].push_back(edge(vi[i],wi[i]));
dij1.G[vi[i]].push_back(edge(ui[i],wi[i]));
}
dij1.dijkstra(s);
ll ans1=0;
for(int i=1;i<=v;i++){
ans1=max(ans1,dij1.d[i]);
}
for(int i=1;i<=k-1;i++){
mix(ki[i],ki[i+1]);
}
// for(int i=1;i<=v;i++){
// cout<<pre[i]<<endl;
// }
for(int i=1;i<=e;i++){
if(Find(ui[i])==Find(ki[1])&&Find(vi[i])==Find(ki[1])){continue;}
dij2.G[Find(ui[i])].push_back(edge(Find(vi[i]),wi[i]));
dij2.G[Find(vi[i])].push_back(edge(Find(ui[i]),wi[i]));
}
dij2.dijkstra(Find(ki[1]));
ll ans2=0;
for(int i=1;i<=v;i++){
if(Find(i)==Find(ki[1]))ans2=max(ans2,1ll*0);
else {ans2=max(ans2,dij2.d[i]);}
}
//cout<<ans1<<" "<<ans2<<endl;
if(ans1<=ans2*c){//注意等号
printf("%lld\n",ans1);
}else printf("%lld\n",ans2);
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mem(s) memset(s, 0, sizeof(s))
const ll INF = 1e18;
const double eps = 1e-8;
const int maxn = 1e3+5;
struct edge{int to,cost;
edge(){}
edge(int v,int w){to=v;cost=w;}
};
typedef pair < ll,int > P;
int n,m,s,k,c;
vector<edge>G[maxn*maxn];
ll d[maxn*maxn];
void dijkstra(int s){
priority_queue<P,vector<P>,greater<P> >que;
for(int i=1;i<=n+1;i++)d[i]=INF;
d[s]=0;
que.push(P(0,s));
while(!que.empty()){
P p=que.top();que.pop();
int v=p.second;
if(d[v]<p.first)continue;
for(int i=0;i<G[v].size();i++){
edge e=G[v][i];
if(d[e.to]>d[v]+e.cost){
d[e.to]=d[v]+e.cost;
que.push(P(d[e.to],e.to));
}
}
}
}
void init(){
for(int i=1;i<=n;i++){
G[i].clear();
}
}
int ki[maxn];
int32_t main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d%d",&n,&m,&s,&k,&c);
for(int i=1;i<=k;i++){
scanf("%d",&ki[i]);
}
init();
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
G[u].push_back(edge(v,w));
G[v].push_back(edge(u,w));
}
dijkstra(s);
ll ans1=0;
for(int i=1;i<=n;i++){
ans1=max(ans1,d[i]);
}
for(int i=1;i<=k-1;i++){
G[ki[i]].push_back(edge(ki[i+1],0));
G[ki[i+1]].push_back(edge(ki[i],0));
}
ll ans2=0;
dijkstra(ki[1]);
for(int i=1;i<=n;i++){
ans2=max(ans2,d[i]);
}
//cout<<ans1<<" "<<ans2<<endl;
if(ans1<=ans2*c){//注意等号
printf("%lld\n",ans1);
}else printf("%lld\n",ans2);
}
return 0;
}