please RT
#include<bits/stdc++.h>
using namespace std;
int head[100001],b[100001]; //head[i]是以i为根的第一条边
// b[i]是i牧场的牛数
bool vis[100001];//入队判断
struct edge{
int from,to,dis,next;//从,到,长度,并列的下一条边
}a[100001];
int eN;//最后一条边的位置,also边的数量
int dis[100001];//i点的最短路径长
void add_bian(int f,int t,int d)//邻接表的形式
{
eN++;
a[eN].from=f;
a[eN].to=t;
a[eN].dis=d;
a[eN].next=head[f];
head[f]=eN;
/*
2 (head[1]) 5(现在的head[1])
/ /
1--3 插入“5 ”-> 1--2
\ \
4 3
4
*/
}
int main()
{
int n,p,c,ans=0x3f;
cin>>n>>p>>c;
int x,y,z;
for(int i=1;i<=n;i++)
{
cin>>x;b[x]++;
}
for(int i=1;i<=c;i++)//绘图
{
cin>>x>>y>>z;
add_bian(x,y,z);
add_bian(y,x,z);
}
for(int i=1;i<=p;i++)//放在i牧场
{
queue<int> q;//以队列里的元素松弛其余元素(类似BFS)
q.push(i);
memset(dis,0x3f,sizeof(dis));//初始化:极大值(为了更新(松弛)最小值)
memset(vis,0,sizeof(vis));//初始化:未入队
dis[i]=0;vis[i]=true;//原点
int cN,cE,nN;//最新节点
while(!q.empty())
{
cN=q.front();//取出最新节点
q.pop();
vis[cN]=false;//取出所以不在队中
cE=head[cN];//松弛对象
while(cE>0)
{
nN=a[cE].to;//a->b nN=b
if(dis[nN]>dis[cN]+a[cE].dis)
{//如果 以前的 > 最新节点+边权
dis[nN]=dis[cN]+a[cE].dis;//那么更新他~
if(vis[nN]==false)
{
q.push(nN);
vis[nN]=true;
}
}
cE=a[cE].next;//转移松弛对象
}
}
int t=0;
for(int j=1;j<=p;j++)
{
t+=b[j]*dis[j];
}
ans=min(ans,t);
}
cout<<ans;
return 0;
//完结撒花~
}