点击打开链接http://acm.nyist.net/JudgeOnline/problem.php?pid=115
#include <stdio.h>
#include <memory.h>
const int M=1010;
int dist[M],s[M],g[M][M];
int main()
{
int t,i,j,k,a,b,n,m,p,q,c[M];
scanf("%d",&t);
while(t--)
{
memset(g,0,sizeof(g));
memset(s,0,sizeof(s));
memset(c,0,sizeof(c));
scanf("%d%d%d%d",&m,&n,&p,&q);
for(i=1;i<=n;i++)
{
dist[i]=9999;
}
for(i=1;i<=m;i++)
{
scanf("%d",&k);
c[i]=k;
}
for(i=1;i<=p;i++)
{
scanf("%d%d%d",&a,&b,&k);
g[a][b]=k;
g[b][a]=k;
if(a==q)
{
dist[b]=k;
}
if(b==q)
{
dist[a]=k;
}
}
s[q]=1; //暴乱city q为源点
dist[q]=0;
while(1) //每次加入集合的点 都是在未收入集合中的点之中 距离源点最近的点
{
int min=9999;
for(i=1;i<=n;i++)
{
if(dist[i]<min&&(s[i]==0))
{
min=dist[i];
k=i;
}
} //按路径递增 收入顶点
if(min==9999) break;
s[k]=1;
dist[k]=min;
for(i=1;i<=n;i++)
{
if(s[i]==0&&g[k][i])
{
if(dist[k]+g[k][i]<dist[i]) //k收入集合后 可能更新某些顶点dist值
{
dist[i]=dist[k]+g[k][i];
}
}
}
}
int min=9999;
for(i=1;i<=m;i++)
{
if(min>dist[c[i]])
{
min=dist[c[i]];
}
}
printf("%d\n",min);
}
return 0;
}