城市平乱

来源:互联网 发布:更换字体的软件 编辑:程序博客网 时间:2024/05/05 03:31

城市平乱

时间限制: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

数据保证暴乱的城市是可达的。
输出
对于每组测试数据,输出第一支部队到达叛乱城市时的时间。每组输出占一行
样例输入
13 8 9 81 2 31 2 12 3 21 4 22 5 33 6 24 7 15 7 35 8 26 8 2 
直接套模板:
 #include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<climits>#include<queue>#include<algorithm>using namespace std;#define N 1000#define MAX INT_MAX >> 1#define CLR(arr, what) memset(arr, what, sizeof(arr))int nodenum, edgenum;int map[N][N], dis[N];bool visit[N];int SPFA(int src, int des){    queue<int> q;    CLR(visit, false);    for(int i = 1;i <= nodenum; ++i)        dis[i] = MAX;    dis[src] = 0;    visit[src] = true;    q.push(src);    while(!q.empty())    {        int cur = q.front();        q.pop();        visit[cur] = false; //出队标记为false        for(int i = 1; i <= nodenum; ++i)        {            if(dis[i] > dis[cur] + map[cur][i]) //没有2个集合,和Dijkstra有本质区别            {                dis[i] = dis[cur] + map[cur][i]; //能松弛就松弛                if(!visit[i]) //不在队列中则加入,然后更新所有以前经过此点的最短路径                {                    q.push(i);                    visit[i] = true;                }            }        }    }    return dis[des];}int main(){     int start, end, cost;    int answer;    int t;    int aim,sr[N],sumarmy;scanf("%d",&t);while(t--)    {    scanf("%d%d%d%d", &sumarmy,&nodenum, &edgenum,&aim);    for(int i=0;i<sumarmy;++i)scanf("%d",&sr[i]);        for(int i = 1; i <= nodenum; ++i)            for(int j = 1; j <= nodenum; ++j)                map[i][j] = MAX;        for(int i = 0; i < edgenum; ++i)        {            scanf("%d%d%d", &start, &end, &cost);            if(cost < map[start][end])                map[start][end] = map[end][start] = cost;        }        int min=MAX;        for(int i=0;i<sumarmy;++i)        {         answer = SPFA(sr[i], aim);         if(min>answer)         min=answer;        }        printf("%d\n",min);        }    return 0;}        
0 0
原创粉丝点击