您的位置:首页 > 其它

NYOJ 115 城市平乱

2017-10-25 13:37 197 查看

城市平乱

时间限制:1000 ms  |  内存限制:65535 KB难度:4描述南将军统领着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
来源《世界大学生程序设计竞赛高级教程·第一册》改编上传者张云聪/*两个顶点之间的最短路径*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 0x3fff
int city[210];//部队所在城市编号
int m[1010][1010];//城市与城市之间距离(表示图)
int lowcost[maxn];//lowcost[i]存储起点到i城市的最短距离
int visit[maxn];//存储该点是否已经加入到集合S(已经确定最小权值的集合)中 
int Dijkstra(int v,int M)
{
memset(lowcost,maxn,sizeof(lowcost));
for(int i=1;i<=M;i++)
{
lowcost[i]=m[v][i];
visit[i]=0;//0表示该点还未加入到集合S中 
}
visit[v]=1;
for(int i=1;i<M;i++)
{
int min=maxn;
int minn=0;
for(int j=1;j<=M;j++)
if(lowcost[j]<min&&visit[j]!=1)//
{
min=lowcost[j];
minn=j;
}
visit[minn]=1;
for(int k=1;k<=M;k++)
{
if(lowcost[k]>m[minn][k]+min)
lowcost[k]=m[minn][k]+min;
}
}

int main()
{
int T,N,M,P,Q,a,b,t;
scanf("%d",&T);
while(T--)
{
memset(m,0,sizeof(m));
memset(city,0,sizeof(city));
scanf("%d %d %d %d",&N,&M,&P,&Q);
for(int i=1;i<=N;i++)
scanf("%d",&city[i]);
for(int i=1;i<=M;i++)
for(int j=1;j<=M;j++)
m[i][j]=maxn;
for(int i=1;i<=M;i++)
m[i][i]=0;
for(int i=0;i<P;i++)
{
scanf("%d %d %d",&a,&b,&t);
m[a][b]=t;
m[b][a]=t;

Dijkstra(Q,M);
int temp=maxn;
for(int i=1;i<=N;i++)
{
if(lowcost[city[i]]<temp)
temp=lowcost[city[i]];
}
printf("%d\n",temp);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: