城市平乱


1000 ms  |  内存限制: 65535


描述

南将军统领着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

第一次做最短路,看了看dijkstra的思想,就想着自己做做,结果悲剧了。不知道如何存贮点了,用的数组一直错误,唉。最后还是百度的,用队列。

dijkstra思想就在这个图片里面。

nyoj115 城市平乱(dijkstra算法)_dijkstra算法

这是这位大牛讲的dijkstra思想。​​点击打开链接​

#include <stdio.h>
#include <string.h>
#include <queue>
#define inf 0x3fffffff
using namespace std;
int buDui[105],map[1005][1005],vis[1005],m,stamp[1005];
queue<int> s;
int dijkstra(int star,int end,int min)
{
s.push(star);
while(!s.empty())
{
star=s.front();
for(int i=1;i<=m;i++)
{
if(i!=star&&map[star][i]&&map[star][i]+stamp[star]<stamp[i]&&!vis[i])
{
s.push(i);
stamp[i]=map[star][i]+stamp[star];//stamp数组更新star到i的距离
}
}
vis[star]=1;
s.pop();
}
return stamp[end];
}
int main()
{
int ncase,min,p,q,n,x,a,b,cost;
scanf("%d",&ncase);
while(ncase--)
{
memset(map,0,sizeof(map));
scanf("%d %d %d %d",&n,&m,&p,&q);
for(int i=0;i<n;i++)
scanf("%d",&x),buDui[i]=x;
for(int i=0;i<p;i++)
{
scanf("%d %d %d",&a,&b,&cost);
map[a][b]=map[b][a]=cost;
}
min=inf;
for(int i=0;i<n;i++)
{
memset(stamp,100,sizeof(stamp));
memset(vis,0,sizeof(vis));
stamp[buDui[i]]=0;
int result=dijkstra(buDui[i],q,inf);
if(result<min)
min=result;
}
printf("%d\n",min);
}
return 0;
}