CSP day2T3 樹的重心

2021-09-29 20:25:02 字數 1232 閱讀 5461

考場上看到標題樹的重心!!!什麼,完了,忘記怎麼求樹的重心了。

好了,回歸正題。

這道題出題人給的部分分很有講究的。

此題非正解給了很高的分,足足有75分。

接下來我們講一下正解:

因為對於一棵二叉樹的根,若它本身不為重心,則重心一定在其重兒子的子樹上。因為該樹深度較小,我們可以重兒子倍增的方法,先dfs一遍,更新出其重兒子與子樹大小,再一次dfs進行換根,對於一條要刪的邊,讓其乙個端點作為根,分別求出重心即可。

#include#include#include#include#include#define maxn 3000005

using namespace std;

typedef long long ll;

#define int ll

int t,n,f[maxn],f1[maxn];

int from[maxn],to[maxn];

int nxt[maxn],ans;

int tot,head[maxn];

int hs1[maxn],hs2[maxn],hs3[maxn];

int ps[maxn][20],sum[maxn],sum2[maxn];

templatevoid read(_t &x)

while(s>='0'&&s<='9')

x*=f;

}void addedge(int u,int v)

void dfs(int u,int fa)

ps[u][0]=hs1[u];

for(int i=1;i<18;i++)

ps[u][i]=ps[ps[u][i-1]][i-1];

}int tann(int u,int num)

void dfs2(int u,int fa)

hs3[u]=ps[u][0]=hs1[u];f1[u]=f[u];

for(int j=1;j<18;j++)

ps[u][j]=ps[ps[u][j-1]][j-1];

sum2[u]=sum[u];

}signed main()

for(int i=1;idfs(1,0);

for(int i=1;i<=n;i++)

ans=0;dfs2(1,0);

printf("%lld\n",ans);

} return 0;

}

CSP S2019 D2T3 樹的重心

小簡單正在學習離散數學,今天的內容是圖論基礎,在課上他做了如下兩條筆記 乙個大小為 n nn 的樹由 n nn 個結點與 n 1 n 1 n 1 條無向邊構成,且滿足任意兩個結點間有且僅有一條簡單路徑。在樹中刪去乙個結點及與它關聯的邊,樹將 為若干個子樹 而在樹中刪去一條邊 保留關聯結點,下同 樹將...

CSP 2019 Day2 T3 樹的重心

題目鏈結 首先有這樣乙個結論 一顆樹的重心要麼是根節點要麼在它重兒子的子樹裡 這個結論十分顯然在這裡就不證明了 於是我們第一遍 dfs 求出以1節點為根時每個點的重兒子和次重兒子 因為會斷掉重兒子的這條邊 以及 pr 表示從 u 節點開始每次沿重兒子跳 2 i 步跳到的點的位置 對於第二次 dfs ...

判斷樹T2是否為T1的子樹

你有兩顆非常大的二叉樹 t1,有幾百萬個節點 t2有幾百個節點。設計乙個演算法,判斷t2是否為t1的子樹。如果t1有乙個節點n,其子樹與t2一模一樣,則t2為t1的子樹。也就是說,從節點n 處把樹砍斷,得到的樹與t2完全相同。方法一 在規模較小且較簡單的問題中,我們可以建立乙個字串,表示中序和前序遍...