本來想學並查集的,看了黃學長的部落格,有道題叫《愚蠢的寵物》,就看了看,然而這道題和並查集並沒有多大關係,而是一道最近公共祖先的題,就學了最近公共祖先,以這道題為例,我所了解的求法有3種:
1、是黃學長的方法。記錄x和y到每個節點的路徑長度,求到每個節點的路徑長度和,最小的乙個就是答案。**是黃學長的
#include
#include
#include
using
namespace
std;
const
int maxn = 1000005;
int f[maxn], a[maxn], b[maxn], x, y;
int main()
for (int i = 1; i < n; i++)
scanf("%d %d", &x, &y);
for (int i = 0; i < n; i++)
int mn = 999999, ans;
for (int i = 1; i <= n; i++)
}printf("%d\n", ans);
return
0;}
學到了memset的黑科技用法,但是其實用fill就行了
2、傳統的求最近公共祖先的方法。求x和y到根節點的深度,先讓深的跳到和淺的一層,然後他們一起向上跳,相遇的那個點就是答案
#include
#include
#include
#include //包含各種極限值的標頭檔案 limits 極限
using
namespace
std;
const
int maxn = 1000005;
int a[maxn], b[maxn], f[maxn] ,dep[maxn];
vector
s[maxn];
void depth(int i, int d) //求樹的深度
}int main()
for (int i = 1; i < n; i++)
int x, y; //盡量讓乙個變數只表示乙個意思
scanf("%d %d", &x, &y);
depth(1, 1);//這樣就把所有節點的深度都求完了!!!
if (dep[x] < dep[y])
while (dep[x] > dep[y])
while (x != y)
printf("%d\n", x);
return
0;}
學到了求樹的深度的函式,這個應該經常用
還有一種以2的次方的步伐往上跳的倍增的演算法,我不會
3、標記x往上走經過的每乙個點,再讓y往上走,遇到的第乙個被標記的點就是答案
#include
#include
const
int maxn = 1000005;
int f[maxn];
bool v[maxn];
void dfs(int i) //不是真正的dfs
v[i] = true;
if (i != 1)
}int main()
scanf("%d %d", &x, &y);
dfs(x), dfs(y);
return
0;}
**不是我自己寫的 rqnoj28 Stupid 愚蠢的寵物
題目描述 背景大家都知道,sheep有兩隻可愛的寵物 乙隻叫神牛,乙隻叫神菜 有一天,sheep帶著兩隻寵物到狗狗家時,這兩隻可愛的寵物竟然迷路了 描述狗狗的家因為常常遭到貓貓的攻擊,所以不得不把家裡前院的路修得非常複雜。狗狗家前院有n個連通的分叉結點,且只有n 1條路連線這n個節點,節點的編號是1...
PID28 Stupid 愚蠢的寵物
題鏈 題目描述 背景大家都知道,sheep有兩隻可愛的寵物 乙隻叫神牛,乙隻叫神菜 有一天,sheep帶著兩隻寵物到狗狗家時,這兩隻可愛的寵物竟然迷路了 描述狗狗的家因為常常遭到貓貓的攻擊,所以不得不把家裡前院的路修得非常複雜。狗狗家前院有n個連通的分叉結點,且只有n 1條路連線這n個節點,節點的編...
PID28愚蠢的寵物(dfs 類似找最短公共祖先)
描述 狗狗的家因為常常遭到貓貓的攻擊,所以不得不把家裡前院的路修得非常複雜。狗狗家前院有n個連通的分叉結點,且只有n 1條路連線這n個節點,節點的編號是1 n 1為根節點 sheep的寵物非常笨,他們只會向前走,不會退後 只向雙親節點走 sheep想知道他們最早什麼時候會相遇 即步數最少 n的範圍 ...