NYOJ115 城市平亂 【SPFA】,nyoj115spfa
城市平亂時間限制: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
-
範例輸出
-
4
-
來源
-
《世界大學生程式設計競賽進階教程·第一冊》改編
-
上傳者
-
張雲聰
忘了是無向圖,WA了好幾次-_-|||
#include <stdio.h>#include <string.h>#include <queue>#define maxn 1010#define maxm 200010#define inf 0x3f3f3f3fint head[maxn];struct Node { int v, dis, next;} E[maxm];bool vis[maxn];int dist[maxn], tar[maxn];int n, m, p, q, id;void addEdge(int u, int v, int dis) { E[id].v = v; E[id].dis = dis; E[id].next = head[u]; head[u] = id++;}void getMap() { scanf("%d%d%d%d", &n, &m, &p, &q); int i, u, v, dis; id = 0; memset(head, -1, sizeof(int) * (m + 1)); for(i = 0; i < n; ++i) scanf("%d", &tar[i]); while(p--) { scanf("%d%d%d", &u, &v, &dis); addEdge(u, v, dis); addEdge(v, u, dis); }}void SPFA() { std::queue<int> Q; memset(dist, 0x3f, sizeof(int) * (m + 1)); memset(vis, 0, sizeof(bool) * (m + 1)); dist[q] = 0; vis[q] = 1; Q.push(q); int u, v, i; while(!Q.empty()) { u = Q.front(); Q.pop(); vis[u] = 0; for(i = head[u]; i != -1; i = E[i].next) { if(dist[v = E[i].v] > dist[u] + E[i].dis) { dist[v] = dist[u] + E[i].dis; if(!vis[v]) { vis[v] = 1; Q.push(v); } } } }}void solve() { SPFA(); int ans = inf; for(int i = 0; i < n; ++i) if(ans > dist[tar[i]]) ans = dist[tar[i]]; printf("%d\n", ans);}int main() { // freopen("stdin.txt", "r", stdin); int t; scanf("%d", &t); while(t--) { getMap(); solve(); } return 0;}