http://acm.hdu.edu.cn/showproblem.php?pid=2586 LCA问题,本来想写两个的,不知道为什么LCA转RMQ会RE,又找不到数组越界的可能,再用第二种方法Tarjon离线先A了再说 #include <iostream> #define MAXN 40010 using namespace std ; struct Graph { int vex , next , dis ; }; Graph g[MAXN * 2] , Q[300] ; int first[MAXN] , head[MAXN] , set[MAXN] , away[MAXN] , n , m ; bool visited[MAXN] ; void Add (int v , int w , int d , int &j) { g[j].dis = d ; g[j].vex = w ; g[j].next = first[v] ; first[v] = j ++ ; } void Add2 (int v , int w , int &j) { Q[j].dis = -1 ; Q[j].vex = w ; Q[j].next = head[v] ; head[v] = j ++ ; } void Read () { int i , j , v , w , d ; memset (first , -1 , sizeof (first)) ; memset (head , -1 , sizeof (head)) ; memset (visited , false , sizeof (visited)) ; scanf ("%d%d" , &n , &m) ; for (j = 0 , i = 1 ; i < n ; i ++) { scanf ("%d%d%d" , &v , &w , &d) ; Add (v , w , d , j) ; Add (w , v , d , j) ; } for (i = j = 0 ; i < m ; i ++) { scanf ("%d%d" , &v , &w) ; Add2 (v , w , j) ; Add2 (w , v , j) ; } } int Find (int x) { if (x == set[x]) return x ; set[x] = Find (set[x]) ; return set[x] ; } void DFS (int v , int dis) { int i ; set[v] = v ; visited[v] = true ; away[v] = dis ; for (i = head[v] ; i != -1 ; i = Q[i].next) if (visited[Q[i].vex]) Q[i].dis = away[v] + away[Q[i].vex] - 2 * away[Find (set[Q[i].vex])] ; for (i = first[v] ; i != -1 ; i = g[i].next) if (!visited[g[i].vex]) { DFS (g[i].vex , dis + g[i].dis) ; set[g[i].vex] = v ; } } void Print () { int i , j ; for (i = j = 0 ; i < m ; i ++ , j += 2) if (Q[j].dis != -1) printf ("%d/n" , Q[j].dis) ; else printf ("%d/n" , Q[j + 1].dis) ; } int main () { int t ; scanf ("%d" , &t) ; while (t --) { Read () ; DFS (1 , 0) ; Print () ; } return 0 ; }