Connections between cities HDU - 2874
After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some materials needed can only be produced in certain places. So we need to transport these materials from city to city. For most of roads had been totally destroyed during the war, there might be no path between two cities, no circle exists as well.
Now, your task comes. After giving you the condition of the roads, we want to know if there exists a path between any two cities. If the answer is yes, output the shortest path between them.
Now, your task comes. After giving you the condition of the roads, we want to know if there exists a path between any two cities. If the answer is yes, output the shortest path between them.
InputInput consists of multiple problem instances.For each instance, first line contains three integers n, m and c, 2<=n<=10000, 0<=m<10000, 1<=c<=1000000. n represents the number of cities numbered from 1 to n. Following m lines, each line has three integers i, j and k, represent a road between city i and city j, with length k. Last c lines, two integers i, j each line, indicates a query of city i and city j.OutputFor each problem instance, one line for each query. If no path between two cities, output “Not connected”, otherwise output the length of the shortest path between them.Sample Input
5 3 2 1 3 2 2 4 3 5 2 3 1 4 4 5
Sample Output
Not connected
6
Hint
Hint Huge input, scanf recommended.
题解:尽管可能是森林,但依然可以用DFS+ST,每棵树取一个顶点作为它的根。
1 // ConsoleApplication2.cpp: 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include<cstdio> 6 #include<vector> 7 #include<cstring> 8 #include<iostream> 9 #include<algorithm> 10 using namespace std; 11 typedef long long ll; 12 13 const int max_log = 16; 14 const int maxn = 10005; 15 const int maxm = 10005; 16 17 int n, m, c, tot; 18 int Pa[20][maxn], Fa[maxn], head[maxn], sum[maxn], dp[maxn]; 19 bool use[maxn]; 20 21 struct node { 22 int to, va, next; 23 }e[2*maxm]; 24 25 void Inite() { 26 tot = 0; 27 memset(use, 0, sizeof(use)); 28 memset(sum, 0, sizeof(sum)); 29 memset(head, -1, sizeof(head)); 30 for (int i = 1; i <= n; i++) Fa[i] = i; 31 } 32 33 void addedge(int u, int v, int w) { 34 e[tot].to = v; 35 e[tot].va = w; 36 e[tot].next = head[u]; 37 head[u] = tot++; 38 } 39 40 int Find(int a) { 41 if (a == Fa[a]) return a; 42 return Fa[a] = Find(Fa[a]); 43 } 44 45 void Union(int a, int b) { 46 int x = Find(a); 47 int y = Find(b); 48 if (x == y) return; 49 Fa[x] = y; return; 50 } 51 52 void DFS(int u, int pa, int deep) { 53 use[u] = true; 54 dp[u] = deep; 55 Pa[0][u] = pa; 56 for (int i = head[u]; i != -1; i = e[i].next) { 57 int v = e[i].to; 58 if (pa == v) continue; 59 sum[v] = sum[u] + e[i].va; 60 DFS(v, u, deep + 1); 61 } 62 } 63 64 void Get_pa() { 65 for (int i = 1; i <= n; i++) if (!use[i]) DFS(i, -1, 0); 66 for (int k = 0; k + 1 < max_log; k++) { 67 for (int u = 1; u <= n; u++) { 68 if (Pa[k][u] < 0) Pa[k + 1][u] = -1; 69 else Pa[k + 1][u] = Pa[k][Pa[k][u]]; 70 } 71 } 72 } 73 74 int Lca(int u, int v) { 75 if (dp[u] > dp[v]) swap(u, v); 76 for (int k = 0; k < max_log; k++) if ((dp[v] - dp[u]) >> k & 1) v = Pa[k][v]; 77 if (u == v) return u; 78 for (int k = max_log - 1; k >= 0; k--) { 79 if (Pa[k][u] != Pa[k][v]) { 80 u = Pa[k][u]; 81 v = Pa[k][v]; 82 } 83 } 84 return Pa[0][u]; 85 } 86 87 88 int main() 89 { 90 while (scanf_s("%d%d%d", &n, &m, &c) != EOF) { 91 Inite(); 92 for (int i = 0; i < m; i++) { 93 int u, v, w; 94 scanf_s("%d%d%d", &u, &v, &w); 95 Union(u, v); 96 addedge(u, v, w); 97 addedge(v, u, w); 98 99 } 100 if(m != 0) Get_pa(); 101 for (int i = 0; i < c; i++) { 102 int u, v; 103 scanf_s("%d%d", &u, &v); 104 int x = Find(u); 105 int y = Find(v); 106 if (x != y) printf_s("Not connected\n"); 107 else { 108 int ans = Lca(u, v); 109 printf_s("%d\n", sum[u] - sum[ans] + sum[v] - sum[ans]); 110 } 111 } 112 } 113 return 0; 114 }

浙公网安备 33010602011771号