POJ 1655 - Balancing Act
2014-04-30 21:36
239 查看
裸的树的重心,要注意的问题是此题的边并没有给出准确的父子拓扑关系,所以需要建双向的边,所以以后要看清题意做仔细分析。
可以知道一个结点的子树必定是 它的拓扑子树 和 根树去掉这个拓扑结点树本身,思路也就很明显了。
提交记录:
可以知道一个结点的子树必定是 它的拓扑子树 和 根树去掉这个拓扑结点树本身,思路也就很明显了。
// poj1655 Balancing Act #include <iostream> #include <cstring> #define NDEBUG #ifndef NDEBUG #include <cstdio> #endif #define MAXN 20005 using namespace std; int N; int edgefw[MAXN*2], edge[MAXN*2], head[MAXN], eptr; #define EI(j, k) ({ \ edge[eptr] = k, edgefw[eptr] = head[j]; \ head[j] = eptr++; \ }) int dp[MAXN], dp2[MAXN]; char vis[MAXN]; void dfs(int i) { vis[i] = 1; int p, maxk = 0, sumn = 1; for(p = head[i]; p>=0; p = edgefw[p]) { int t = edge[p]; if (!vis[t]) { if (!dp2[t]) dfs(t); sumn += dp2[t]; if (maxk < dp2[t]) maxk = dp2[t]; } } if (sumn != N && N - sumn > maxk) maxk = N - sumn; dp[i] = maxk, dp2[i] = sumn; } int main(void) { #ifndef NDEBUG freopen("poj1655.in", "r", stdin); #endif // NDEBUG int T; for(cin >> T; T; --T) { cin >> N; memset(vis, 0, sizeof(vis)); memset(dp2, 0, sizeof(dp2)); memset(head, -1, sizeof(head)), eptr = 0; int i, j, root; root = 0; for(i=0; i<N-1; ++i) { int k; cin >> j >> k; --j,--k; EI(j, k), EI(k, j); if (root == k) root = j; } dfs(root); j = 0; for(i = 1; i < N; ++i) if (dp[i] < dp[j]) j = i; cout << j+1 << ' ' << dp[j] << endl; } return 0; }
提交记录:
Accepted | 1292K | 610MS | G++ | 1269B | 2014-04-30 21:28:41 |
相关文章推荐
- poj-1655 Balancing Act(树的重心+树形dp)
- POJ 1655 Balancing Act(树的重心)
- poj 1655 Balancing Act(树dp)
- POJ 1655 Balancing Act 树的重心
- POJ 1655 Balancing Act【树的重心】
- poj 1655 Balancing Act
- Poj 1655 Balancing Act (树的重心)
- poj 1655 Balancing Act 求树的重心
- poj 1655 Balancing Act
- POJ 1655 Balancing Act(求树的重心)
- poj 1655 Balancing Act(树形DP)
- POJ1655 Balancing Act(树的重心)
- POJ 1655 Balancing Act 笔记
- poj 1655 Balancing Act (树形dfs)
- POJ 1655 - Balancing Act 树形DP
- POJ 1655 Balancing Act 树形DP入门题
- POJ 1655 Balancing Act (树的重心,常规)
- POJ 1655 Balancing Act 焦点树
- poj 1655 Balancing Act(求树的重心)
- poj 1655 Balancing Act(树的重心)