HDU 2874 Connections between cities (LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874
题意是给你n个点,m条边(无向),q个询问。接下来m行,每行两个点一个边权,而且这个图不能有环路。然后接下来q行,每行给你两个点,问你这两个点的最短距离是多少,要是不相连,则输出一串英文。
首先想到的是用(二分)倍增LCA,但是这题的坑点是两个点可能不在同一个图中,所以我dfs的时候用block[i]标记这个点属于哪一个图中,要是这个点在同一个图中,答案就是cost[u] + cost[v] - 2*cost[lca(u , v)]。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 const int MAXN = 10005; 7 struct data { 8 int next , to , w; 9 }edge[MAXN * 4]; 10 int head[MAXN] , par[MAXN * 3][15] , dep[MAXN] , cont , cost[MAXN] , block[MAXN]; 11 12 void init() { 13 cont = 0; 14 //memset(par , -1 , sizeof(par)); 15 memset(head , -1 , sizeof(head)); 16 memset(block , 0 , sizeof(block)); 17 } 18 19 inline void add(int u , int v , int w) { 20 edge[cont].next = head[u]; 21 edge[cont].to = v; 22 edge[cont].w = w; 23 head[u] = cont++; 24 } 25 26 void dfs(int u , int p , int d , int node , int w) { 27 dep[u] = d; 28 par[u][0] = p; 29 block[u] = node; 30 cost[u] = w; 31 int v; 32 for(int i = head[u] ; ~i ; i = edge[i].next) { 33 v = edge[i].to; 34 if(v == p) 35 continue; 36 dfs(v , u , d + 1 , node , w + edge[i].w); 37 } 38 } 39 40 int lca(int u , int v) { 41 if(dep[u] < dep[v]) 42 swap(u , v); 43 for(int k = 0 ; k < 15 ; k++) { 44 if((dep[u] - dep[v]) >> k & 1) { 45 u = par[u][k]; 46 } 47 } 48 if(u == v) 49 return v; 50 for(int k = 14 ; k >= 0 ; k--) { 51 if(par[u][k] != par[v][k]) { 52 u = par[u][k]; 53 v = par[v][k]; 54 } 55 } 56 return par[u][0]; 57 } 58 59 int main() 60 { 61 int n , m , q , u , v , w; 62 while(~scanf("%d %d %d" , &n , &m , &q)) { 63 init(); 64 for(int i = 0 ; i < m ; i++) { 65 scanf("%d %d %d" , &u , &v , &w); 66 add(u , v , w); 67 add(v , u , w); 68 } 69 int f = 0; 70 for(int i = 1 ; i <= n ; i++) { 71 if(!block[i]) { 72 dfs(i , -1 , 0 , ++f , 0); 73 } 74 } 75 for(int k = 0 ; k < 14 ; k++) { 76 for(int i = 1 ; i <= n ; i++) { 77 if(par[i][k] <= 0) 78 par[i][k + 1] = par[i][k]; 79 else 80 par[i][k + 1] = par[par[i][k]][k]; 81 } 82 } 83 while(q--) { 84 scanf("%d %d" , &u , &v); 85 if(block[u] != block[v]) { 86 printf("Not connected\n"); 87 } 88 else { 89 printf("%d\n" , cost[u] + cost[v] - 2 * cost[lca(u , v)]); 90 } 91 } 92 } 93 }