1. 程式人生 > >RQNOJ28 愚蠢的寵物(LCA / 並查集)

RQNOJ28 愚蠢的寵物(LCA / 並查集)

題意分析

其實是一道裸地最近公共祖先的題目,但是還是可以用並查集水過去。

怎麼水呢?
合併時記錄一下深度,預設節點1深度為0。
最後要求兩個節點的最近公共祖先,那麼首先讓深度大的那個節點總下往上找,最後一定是回到根節點1,在網上找的過程中,一邊找一邊記錄一下經過哪些了節點,用bool陣列儲存。
然後讓另外一個深度比較小的節點找根節點,如果在途中遇到了第一個節點經過到的節點,直接返回即可。
然後就水過去了。

程式碼總覽

#include<bits/stdc++.h>
using namespace std;
const int nmax = 1000005;
int fa[nmax];
int
deep[nmax]; bool isin[nmax]; int n; int findset(int x){ while(fa[x] != x){ isin[x] = true; x = fa[x]; } return x; } void unionset(int x, int y){ fa[y] = x; deep[y] = deep[x] + 1; } int findans(int a, int b){ int x; if(deep[a]>deep[b]){ findset(a); x = b; }else
findset(b),x = a; while(x != fa[x]){ if(isin[x]) return x; else x = fa[x]; } } int main(){ while(scanf("%d",&n)!=EOF){ int a,b; for(int i = 0;i<n;++i) fa[i] = i; for(int i = 0;i<n-1;++i){ scanf("%d %d",&a,&b); unionset(a,b); } scanf
("%d %d",&a,&b); // int ans = findans(a,b); printf("%d\n",findans(a,b)); } return 0; }