考場上看到標題樹的重心!!!什麼,完了,忘記怎麼求樹的重心了。
好了,回歸正題。
這道題出題人給的部分分很有講究的。
此題非正解給了很高的分,足足有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完全相同。方法一 在規模較小且較簡單的問題中,我們可以建立乙個字串,表示中序和前序遍...