POJ1655树的重心 问删除哪个点,使余下的各个子树结点个数的最大值最小.
2015-08-30 21:36
323 查看
#include <stdio.h> #include <stdlib.h> #include <string.h> #define Max(a,b) (a>b?a:b) #define Min(a,b) (a<b?a:b) #define nMax 20010 struct Edge{ int v; int next; }edge[2 * nMax];//保存双向图 int preEdge[nMax];//同一个起点的上一条边 int n; bool flag[nMax]; int childNum[nMax];//每个节点下的节点总数 int min; int childMax[nMax];//每个节点去掉后其他子树最多点数 int dfs(int root) { flag[root] = true; int p = preEdge[root];//以root为起点的边的标示也就是edge的下标 while (p) { int v = edge[p].v;//root连接的点 if (!flag[v]) { childNum[root] += dfs(v);//求root点下的所有节点 childMax[root] = Max(childNum[edge[p].v], childMax[root]);//求root点下孩子节点中的最大值 } p = edge[p].next;//以root为起点的上一条边 } childMax[root] = Max(n - childNum[root], childMax[root]);//root下孩子节点中的最大值和祖先节点总数的最大值作为本节点的最大值 return childNum[root];//返回本节点的总数 } int main() { int t; int u, v; while (scanf("%d", &t) != EOF) { while (t --) { memset(preEdge, 0, sizeof(preEdge)); memset(flag, false, sizeof(flag)); min = 0x0FFFFFFF; scanf("%d", &n); for (int i = 1; i < 2 * (n - 1); i += 2)//建图 { scanf("%d %d", &u, &v); edge[i].v = v; edge[i].next = preEdge[u]; preEdge[u] = i; edge[i + 1].v = u; edge[i + 1].next = preEdge[v]; preEdge[v] = i + 1; } if (n == 1) { printf("1 0\n"); continue; } //memset(childNum, 0, sizeof(childNum)); for (int i = 1; i <= n; ++ i) { childNum[i] = 1; childMax[i] = -1; } dfs(1);//dfs int mMin = 0x0FFFFFFF, k; for (int i = 1; i <= n; ++ i)//求最小值 { if (mMin > childMax[i]) { k = i; mMin = childMax[i]; } } printf("%d %d\n", k, mMin); } } return 0; }
相关文章推荐
- OSPF虚链路
- Django之第一个app<18>
- 人无趣的原因
- img src="#"或者src="" 会发送请求的问题
- 关于c++中字符串的输入问题
- Swift2.0不深入只浅出入门教程-01-The Basic
- Longest Consecutive Sequence 数组连续数字的情况
- HTTP状态码
- error: xml2-config not found. Please check your libxml2 installation.
- 开发环境、基础语法、数组
- 赋值运算符
- Gas Station
- pandas dataframe 分组聚合时,分组组名并入列的方法
- Linux常用命令总结
- Ant与eclispe
- 图论——Dijkstra(normal版)
- sql server2005和oracle分页查询语句
- 最长01串(贪心)
- LeetCode Interleaving String DP
- hdu5416CRB and Tree 异或