http://codeforces.com/contest/1343/problem/E
题意:
给出一个无向图,m条边,有m个值,要求一一对应。现在从a到b再到c的路程最短。
解析:
显然找到一个点d,bd算两次,ad和cd算一次。
代码:
/*
* Author : Jk_Chen
* Date : 2020-04-21-23.15.41
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=2e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
#define rep_e(i,p,u) for(int i=head[p],u=to[i];i;i=nex[i],u=to[i])
int head[maxn],to[maxn<<1],nex[maxn<<1],now;
void add(int a,int b){
nex[++now]=head[a];head[a]=now;to[now]=b;
}
void init_edge(){
memset(head,0,sizeof head);
now=0;
}
/*_________________________________________________________edge*/
int n,m;
int dis[3][maxn];
int BFS(int p,int dis[]){
rep(i,1,n)dis[i]=inf;
dis[p]=0;
queue<int>Q;
Q.push(p);
while(!Q.empty()){
p=Q.front();Q.pop();
rep_e(i,p,u){
if(dis[u]>dis[p]+1){
dis[u]=dis[p]+1;
Q.push(u);
}
}
}
}
LL len[maxn];
int main(){
int t=rd;
while(t--){
n=rd,m=rd;
rep(i,1,n)head[i]=0;
now=0;
int a=rd,b=rd,c=rd;
rep(i,1,m)len[i]=rd;
sort(len+1,len+1+m);
rep(i,1,m){
int aa=rd,bb=rd;
add(aa,bb);
add(bb,aa);
}
rep(i,1,m)len[i]+=len[i-1];
BFS(a,dis[0]);
BFS(b,dis[1]);
BFS(c,dis[2]);
LL ans=2e18;
rep(i,1,n){
LL l1=dis[1][i];
LL l2=dis[0][i];
LL l3=dis[2][i];
l2+=l3;
if(l1+l2>m)continue;
ans=min(ans,len[l1]*2ll+(len[l1+l2]-len[l1]));
}
printf("%lld\n",ans);
}
return 0;
}
/*_________________________________________________________end*/