樹的重心:
#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 個操作,操作分為如下五種型別 換根 將乙個指定的節點設定為樹的新根。修改路徑權值 給定兩個節點,將這兩個節點間路徑上的所有節點權值 含這兩個節點 增加乙個給定的值。修改子樹權值 給定乙個節點,將...