版本一:
#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...