题目连接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=115
题目描述
南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市。
他在用这N个部队维护着M个城市的治安,这M个城市分别编号从1到M。
现在,小工军师告诉南将军,第K号城市发生了暴乱,南将军从各个部队都派遣了一个分队沿最近路去往暴乱城市平乱。
现在已知在任意两个城市之间的路行军所需的时间,你作为南将军麾下最厉害的程序员,请你编写一个程序来告诉南将军第一个分队到达叛乱城市所需的时间。
注意,两个城市之间可能不只一条路。
输入
输出
样例输入
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
分析:基本上套用Dijkstra的模板 由于驻扎部队都进行寻找,可以依次寻找,进行判断,找出最小值
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100000+10
int n,m,p,q;
int vis[1100],mark[1100],map[1100][1100],dis[1100];//dis数组是记录驻扎城市所在的编号、mark数组 1表示已用、0还未用、map[a][b]表示a到b的距离、vis[i]表示第一个起点到i的距离
int Dijkstra(int x)
{
int k,MIN;
for(int i=1;i<=m;i++)
{
vis[i]=map[x][i];
mark[i]=0;
}
mark[x]=1;
for(int i=1;i<=m;i++)
{
MIN=maxn;
for(int j=1;j<=m;j++)
{
if(!mark[j]&&vis[j]<MIN)
{
MIN=vis[j];
k=j;
}
}
mark[k]=1;
for(int j=1;j<=m;j++)
{
if(!mark[j]&&vis[k]+map[k][j]<vis[j])
vis[j]=vis[k]+map[k][j];
}
}
return vis[q];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d %d",&n,&m,&p,&q);
for(int i=1;i<=n;i++)
scanf("%d",&dis[i]);
//for(int i=1;i<=n;i++)
//printf("%d\n",dis[i]);
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
map[i][j]=maxn;
for(int i=1;i<=p;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
map[a][b]=map[b][a]=c;
}
int min=maxn;
for(int i=1;i<=n;i++)
{
if(Dijkstra(dis[i])<min)
min=vis[q];
}
printf("%d\n",min);
}
return 0;
}