求树的重心 POJ 1655、POJ 3107 树形DP
2016-10-18 11:55
441 查看
树的重心:在树中删去重心后,剩下的子树的最大子树大小最小,则这个节点为重心
POJ 1655:直接求树的重心
思路:递归每个节点的时候,记录一下这个节点所有子树的大小和,然后记录最大子树的大小,维护最小的最大子树大小和相应的节点即可
代码:
POJ 3107 输出所有的重心
思路:同上,不过要记录一下所有的节点
POJ 1655:直接求树的重心
思路:递归每个节点的时候,记录一下这个节点所有子树的大小和,然后记录最大子树的大小,维护最小的最大子树大小和相应的节点即可
代码:
#include <iostream> #include <cstdio> #include <cstring> #define sf scanf #define pf printf using namespace std; const int maxn = 20000 + 5,INF = 1e9; int son[maxn],ans,ans_size; struct Edge{ int v,pre; }Edges[maxn * 2]; int head[maxn],tot,n; void Init(){ memset(head,-1,sizeof head),tot = 0; } void Add(int u,int v){ Edges[tot].v = v; Edges[tot].pre = head[u]; head[u] = tot++; } void DFS(int u,int fa){ int tmp = 0; son[u] = 0; for(int i = head[u];~i;i = Edges[i].pre){ int v = Edges[i].v; if(v == fa) continue; DFS(v,u); tmp = max(tmp,son[v] + 1); son[u] += son[v] + 1; } tmp = max(tmp,n - 1 - son[u]); if(tmp < ans_size || (tmp == ans_size && u < ans)){ ans_size = tmp; ans = u; } } int main(){ int T;sf("%d",&T); while(T--){ Init(); sf("%d",&n); for(int i = 0;i < n - 1;++i){ int u,v;sf("%d %d",&u,&v); Add(u,v); Add(v,u); } memset(son,0,sizeof son); ans_size = INF; DFS(1,0); pf("%d %d\n",ans,ans_size); } }
POJ 3107 输出所有的重心
思路:同上,不过要记录一下所有的节点
#include <cstring> #include <iostream> #include <cstdio> #include <vector> #include <algorithm> #define sf scanf #define pf printf using namespace std; const int maxn = 50000 + 5,INF = 2e9; struct Edge{ int v,pre; }Edges[maxn * 2]; int head[maxn],ans_size,tot,n,son[maxn]; vector<int> ans; void init(){ memset(head,-1,sizeof head),tot = 0; memset(son,0,sizeof son); ans_size = INF; } void Add(int u,int v){ Edges[tot].v = v; Edges[tot].pre = head[u]; head[u] = tot++; } void DFS(int u,int fa){ int tmp = 0;son[u] = 0; for(int i = head[u];~i;i = Edges[i].pre){ int v = Edges[i].v; if(v == fa) continue; DFS(v,u); son[u] += son[v] + 1; tmp = max(tmp , son[v] + 1); }tmp = max(tmp,n - 1 - son[u]); if(tmp < ans_size){ ans.clear();ans.push_back(u);ans_size = tmp; }else if(tmp == ans_size) ans.push_back(u); } int main(){ while(~sf("%d",&n)){ init(); for(int i = 1;i < n;++i){ int u,v;sf("%d %d",&u,&v); Add(u,v); Add(v,u); } DFS(1,0); sort(ans.begin(),ans.end()); int len = ans.size(); for(int i = 0;i < len;++i) pf("%d%c",ans[i]," \n"[i + 1 == len]); } }
相关文章推荐
- poj 1655 and 3107 and 2378 树形dp(树的重心问题)
- 【poj 1655,3107】树的重心(树形dp)
- POJ 1655 树的重心(树形 DP)
- POJ 1655 Balancing Act (树形dp 树的重心)
- POJ1655-树的重心&树形dp-Balancing Act
- poj-1655 Balancing Act(树的重心+树形dp)
- poj1655 Balancing Act【树的重心+树形dp】
- POJ 1655 Balancing Act(求树的重心--树形DP)
- poj 1655 Balancing Act(树的重心,树形dp)
- 【POJ - 1655】Balancing Act 【树形DP 求解树的重心】
- poj 3107 Godfather(树形dp,树的重心)
- poj 1655(树形DP 求解重心)
- poj 1655 Balancing Act 【树形DP 求树的重心】
- poj 1655 树形dp求取树的重心
- poj 1655Balancing Act(找重心,树形dp)
- poj 3107 Godfather 求树的所有重心 树形DP
- poj1655 Balancing Act 【树形DP(很弱)】
- poj 3107(简单的树形dp)
- POJ 3107 Godfather(树形dp)
- POJ 3107 Godfather(树形DP)