题意分析:由题意可知,这个糖可以放在牧场中,但是之后所有的牛都会来到这个地方,依次来求解最小值。
从大的方向上来看,可以看成是一个暴力枚举,就是枚举每个点作为放置糖的起点,之后求解所有牛到这个点的最小值的和,最后,求解和的最小值
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
//根据题意可知所以奶牛到要到放糖的地方进行,所以就是求所有点到第一点的最短路径
const int N =810,M=3000,INF=0x3f3f3f3f;
int n,m,p;
int id[N];
int h[N],e[M],ne[M],w[M],idx;
int dist[N],q[N];
bool st[N];
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int spfa(int start) //起点
{
memset(dist,0x3f,sizeof dist);
dist[start]=0;
int hh=0,tt=1;
q[0]=start;
st[start]=true;
while(hh!=tt)
{
int t=q[hh++];
if(hh==N) hh=0;
st[t]=false;
for(int i=h[t];~i;i=ne[i])
{
int j=e[i];
if(dist[j]>dist[t]+w[i])
{
dist[j]=dist[t]+w[i];
if(!st[j])
{
q[tt++]=j;
if(tt==N) tt=0;
st[j]=true;
}
}
}
}
int res=0;
for(int i=0;i<n;i++)
{
int j=id[i]; //为当前的奶牛的序号
if(dist[j]==INF) return INF; // 如果为INF,显然是这个点无法到达放置糖的地方。
res+=dist[j]; //每个牛到这个点的最小值的总和
}
return res;
}
int main()
{
cin>>n>>p>>m;
for(int i=0;i<n;i++) cin>>id[i];
memset(h,-1,sizeof h);
for(int i=0;i<m;i++)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c),add(b,a,c);//无向图
}
int res=INF;
for(int i=1;i<=p;i++) res=min(res,spfa(i));
cout<<res<<endl;
return 0;
}