当前位置: 代码迷 >> 综合 >> NYOJ - 115 - 城市平乱 ( 最短路 Dijkstra )
  详细解决方案

NYOJ - 115 - 城市平乱 ( 最短路 Dijkstra )

热度:93   发布时间:2023-10-09 17:00:15.0

描述

南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市。

他在用这N个部队维护着M个城市的治安,这M个城市分别编号从1到M。

现在,小工军师告诉南将军,第K号城市发生了暴乱,南将军从各个部队都派遣了一个分队沿最近路去往暴乱城市平乱。

现在已知在任意两个城市之间的路行军所需的时间,你作为南将军麾下最厉害的程序员,请你编写一个程序来告诉南将军第一个分队到达叛乱城市所需的时间。

注意,两个城市之间可能不只一条路。

输入
第一行输入一个整数T,表示测试数据的组数。(T<20)
每组测试数据的第一行是四个整数N,M,P,Q(1<=N<=100,N<=M<=1000,M-1<=P<=100000)其中N表示部队数,M表示城市数,P表示城市之间的路的条数,Q表示发生暴乱的城市编号。
随后的一行是N个整数,表示部队所在城市的编号。
再之后的P行,每行有三个正整数,a,b,t(1<=a,b<=M,1<=t<=100),表示a,b之间的路如果行军需要用时为t

数据保证暴乱的城市是可达的。
输出
对于每组测试数据,输出第一支部队到达叛乱城市时的时间。每组输出占一行
样例输入
1
3 8 9 8
1 2 3
1 2 1
2 3 2
1 4 2
2 5 3
3 6 2
4 7 1
5 7 3
5 8 2
6 8 2 
样例输出
4


题目要求:分别求出从N个城市到Q路径城市的最小值,然后求出哪个城市到Q城市距离最小。

题目思路:Dijkstra算法求出所有结点到Q结点的最短距离,然后找出指定的N的结点中到Q结点的最小距离。


#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1005
#define INF 100000
using namespace std;
int T,n,m,p,q,x,y,z;
int G[N][N],vis[N]; //邻接矩阵,访问标记 
int d[N],ans[105]; //d[i]表示Q结点到i的最短距离 void Dijstra(){memset(vis,0,sizeof(vis));for(int i=1 ;i<=m ;i++) d[i] = (i == q ? 0 : INF);for(int i=1 ;i<=m ;i++){int x,mi=INF;//找出最小的d[y] for(int y=1 ;y<=m ;y++) if(!vis[y]&&d[y]<=mi)mi = d[x=y];vis[x] = 1;//更新到各个点的距离 for(int y=1 ;y<=m ;y++) d[y] = min(d[y],d[x]+G[x][y]);}
}void init(){scanf("%d%d%d%d",&n,&m,&p,&q);for(int i=0 ;i<n ;i++){scanf("%d",&ans[i]);}for(int i=1 ;i<=m ;i++){for(int j=1 ;j<=m ;j++){G[i][j] = (i==j ? 0 : INF);}}for(int i=0 ;i<p ;i++){scanf("%d%d%d",&x,&y,&z);if(G[x][y]>z){G[y][x]=G[x][y]=z;}}
}
int main(){scanf("%d",&T);while(T--){init();Dijstra();int res = INF;for(int i=0 ;i<n ;i++) res = min(res,d[ans[i]]);	printf("%d\n",res);}return 0;
}