樹的換根 重心

2021-10-04 16:07:32 字數 1473 閱讀 7357

樹的重心:

#include

#include

#include

using

namespace std;

#define max(x,y) (x>y?x:y)

const

int n=

1e6+1;

int n;

vector<

int> g[n]

;int son[n]

;//s[v]:表示以結點v為根的子樹的結點個數

bool vis[n]

;int res=n<<

1,tu;

void

dfs(

int v,

int par)

ans=

max(ans,n-son[v]);

//去掉v後,能產生的最大子樹的結點數 :

//要麼在v的子樹中產生,要麼在另一半樹中產生(max=n-son[v],

//即:最大等於n減去v子樹的結點總數)

if(ans}//計算深度和

void

dfsw

(int v,

int k)

}void

solve()

intmain()

solve()

;return0;

}

深搜加動態規劃維護最優解:

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn=

1e6+7;

int head[maxn]

,dep[maxn]

,p[maxn]

,vis[maxn]

,dp[maxn]

,cnt,n;

struct edgee[maxn<<1]

;void

add(

int x,

int y)

,head[x]

=cnt;

}int

dfs(

int x)

}return p[x];}

void

solve

(int x)}}

intmain()

dfs(1)

;memset

(vis,0,

sizeof

(vis));

dp[1]

=dep[1]

;solve(1

);for(

int i=

1; i<=n; i++

)printf

("%d\n"

,m);

return0;

}

HDU Cotree 換根dp,樹的重心

我是看了這位大佬的部落格,感謝大佬他的部落格 題目描述 有兩顆樹,需要在這兩棵樹之間新增一條邊,這樣就變成了一棵樹,求這棵樹任意兩點之間的最小距離和 即 sum sum dis left i,j right 那麼怎樣找重心呢?我們定義sum i 一顆樹中其他點到i點的距離和 sum num i 為i...

CSP2019 樹的重心(樹的重心 倍增 換根)

當年我做這道題時還太嫩了,只能想到暴力。其實如果會了更高的科技這道題只要稍微對暴力優化一下就能ac 我也不會含淚75pts了 廢話不說了,暴力的思路就是列舉每一條邊然後求兩個子樹的重心。直接求重心的複雜度是 o n 的,我們考慮優化到 o log 我們想要求以 x 為根的子樹的重心,首先有個引理 這...

樹鏈剖分換根

描述 給定一棵 n 個節點的樹,初始時該樹的根為 1 號節點,每個節點有乙個給定的權值。下面依次進行 m 個操作,操作分為如下五種型別 換根 將乙個指定的節點設定為樹的新根。修改路徑權值 給定兩個節點,將這兩個節點間路徑上的所有節點權值 含這兩個節點 增加乙個給定的值。修改子樹權值 給定乙個節點,將...