题解 : 以暴乱城市 为 源点 向所有点做最短路径 , 然后检查每个不对到暴乱城市的 最短距离
1 #include<stdio.h>
2 #include<string.h>
3 #include<math.h>
4 #include<iostream>
5 #include<limits.h>
6 #include<algorithm>
7 #include<queue>
8 #include<vector>
9 #include<set>
10 #include<stack>
11 #include<string>
12 #include<sstream>
13 #include<map>
14 #include<cctype>
15 using namespace std;
16 int b[105],a[1005][1005],dis[1005],visited[1005];
17 int main() // 这个可以用Dijkstra来做
18 {
19 int t;
20 scanf("%d",&t);
21 while(t--) // 暴乱城市 可以作为起点 , 然后去看不对到暴乱城市的时间
22 {
23 int n,m,p,q;
24 scanf("%d%d%d%d",&n,&m,&p,&q); // 部队数量 , 城市数量 , 道路数量 , 暴乱城市编号
25 for(int i=0;i<n;i++)
26 scanf("%d",&b[i]);
27 for(int i=0;i<=m;i++)
28 {
29 dis[i]=INT_MAX;
30 for(int j=0;j<=m;j++)
31 a[i][j]=INT_MAX; //谨慎对待 最大值
32 }
33 for(int i=0;i<p;i++)
34 {
35 int c,d,e;
36 scanf("%d%d%d",&c,&d,&e);
37 a[d][c]=a[c][d]=e; //
38 } // 所有的边已经建立完成
39 memset(visited,0,sizeof(visited));//开始核心算法
40 for(int i=1;i<m;i++)
41 dis[i]=a[q][i]; // 图中 每个点 到 已经确定的 距离
42 dis[q]=0;
43 visited[q]=1;
44 int v;
45 for(int i=1;i<=m;i++)
46 {
47 int minn=INT_MAX;
48 for(int j=1;j<=m;j++)
49 {
50 if(minn>dis[j]&&!visited[j])
51 {
52 minn=dis[j];
53 v=j;
54 }
55 } // 得到目前确定区域 最近的 点
56 visited[v]=1;
57 for(int j=1;j<m;j++)
58 {
59 if(!visited[j]&&dis[v]!=INT_MAX&&a[v][j]!=INT_MAX&&dis[v]+a[v][j]<dis[j])
60 dis[j]=dis[v]+a[v][j];
61 }
62 }
63 int minn=INT_MAX;
64 for(int i=0;i<n;i++)
65 {
66 if(minn>dis[b[i]])
67 minn=dis[b[i]];
68 }
69 printf("%d
",minn);
70 }
71 return 0;
72 }