poj1655 樹的重心

2021-10-04 06:46:02 字數 1872 閱讀 8379

版本一:

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn=

200005

;vector<

int> tree[maxn]

;int n,minnode,minbalance;

//minnode當前重心節點

//minbalance當前重心節點的最大子樹節點個數

int d[maxn]

;//d[i]表示以i為根的子樹節點個數

void

dfs(

int u,

int fa)

} maxsub=

max(maxsub,n-d[u]);

if(maxsub}int

main()

minnode=

0; minbalance=

0x3f3f3f3f

;dfs(1

,0);

printf

("%d %d\n"

,minnode,minbalance);}

return0;

}

版本二:

#include

#include

#include

#include

#include

#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

using

namespace std;

const

int maxn =

200005

;const

int maxm =

1000005

;const

int inf=

0x3f3f3f3f

;int n,m,d[maxn]

;///大小陣列

int head[maxn]

,cnt;

///head->是總邊數中的第幾邊,cnt->總邊數

int vis[maxn]

;///

int maxpart[maxn]

,ans=inf;

inline

intread()

while

(c>=

'0'&&c<=

'9') x=

(x<<3)

+(x<<1)

+c-'0'

,c=getchar()

;return x*w;

}struct edge

ed[maxn<<1]

;void

init()

void

addedge

(int u,

int v)

void

dfs(

int x)

maxpart[x]

=max

(maxpart[x]

, n - d[x]);

///這是x的另一顆子樹(無根樹,換根法

if(maxpart[x]

< ans)

}int

main()

dfs(1)

;//隨便乙個點

for(

int i =

1; i <= n; i++)}

return0;

}

poj1655樹的重心

給定一棵樹,找出乙個點x,使得刪去x後,剩下的最大的子樹最小。解法 從上圖知,刪去點i後,形成的森林為點i的若干子樹與i 上方 的部分。s i 表示以i為根的子樹的大小 s i s j 1 s i 1 考慮每個節點i,剩下的最大子樹的大小maxsize i max,故計算出所有的maxsize i ...

poj 1655 樹的重心

題意 給了乙個樹,去掉乙個結點後的子樹的節點數的最大值即平衡值,求最小的平衡值,如果平衡值相同,使節點號最小。思路 其實也就是求樹的重心。樹的重心是找到乙個點使其所有子樹中節點個數最大的子樹的結點數目最小,使生成的樹盡可能平衡。其實 求樹的重心,只需要隨便找個點作為根dfs,求每個節點的每個子樹的節...

poj 1655 樹的重心

因為建立的樹實際上主要是記錄點的無向圖g,dfs u,r 的r是用來防止遍歷子節點時dfs到父節點,還用到了記憶化,並且是在一次dfs時求答案,效率有點低,ac用時300ms include include include include include include include includ...