POJ 2874 LCA 樹上任意兩點距離
阿新 • • 發佈:2019-01-22
本題說了是無環圖,所以就是一片森林了。 而對於樹上的任意兩點,我們可以用LCA求其距離。距離為兩個子節點到根的距離和減去最近祖先到根的距離的2倍。具體畫圖便可看出來。
並且圖是無向圖,所以LCA時需要進行標記
POJ 1986同這道題 基本一樣
/* ID: CUGB-wwj PROG: LANG: C++ */ #include <iostream> #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <cmath> #include <ctime> #define INF 1111111111 #define MAXN 10005 #define MAXM 1000005 #define L(x) x<<1 #define R(x) x<<1|1 #define eps 1e-4 using namespace std; struct node { int v, w; node(){} node(int a, int b){ v = a; w = b;} }; vector<node>tree[MAXN], ask[MAXN]; //tree裡w代表權值,ask裡w代表序號 int dis[MAXN], father[MAXN], vis[MAXN], ans[MAXM]; int n, m, c; void init() { for(int i = 0; i <= n; i++) { dis[i] = 0; father[i] = i; vis[i] = 0; tree[i].clear(); ask[i].clear(); } } int find(int x) { if(father[x] == x) return x; int t = find(father[x]); father[x] = t; return t; } void LCA(int u, int w, int root) { dis[u] = w; father[u] = u; vis[u] = root; int size = tree[u].size(); for(int i = 0; i < size; i++) { if(!vis[tree[u][i].v]) { LCA(tree[u][i].v, tree[u][i].w + w, root); father[tree[u][i].v] = u; } } size = ask[u].size(); for(int i = 0; i < size; i++) { if(vis[ask[u][i].v]) { if(vis[ask[u][i].v] == root) ans[ask[u][i].w] = dis[u] + dis[ask[u][i].v] - 2 * dis[find(ask[u][i].v)]; else ans[ask[u][i].w] = -1; } } } int main() { int u, v, w; while(scanf("%d%d%d", &n, &m, &c) != EOF) { init(); for(int i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v, &w); node tmp1(v, w); node tmp2(u, w); tree[u].push_back(tmp1); tree[v].push_back(tmp2); } for(int i = 1; i <= c; i++) { scanf("%d%d", &u, &v); node tmp1(v, i); node tmp2(u, i); ask[u].push_back(tmp1); ask[v].push_back(tmp2); } for(int i = 1; i <= n; i++) { if(!vis[i]) LCA(i, 0, i); } for(int i = 1; i <= c; i++) { if(ans[i] == -1) printf("Not connected\n"); else printf("%d\n", ans[i]); } } return 0; }