jzoj 1301_treecut_dfs
2017-07-09 16:52
232 查看
题目描述
有一个N个节点的无根树,各节点编号为1..N,现在要求你删除其中的一个点,使分割开的连通块中节点个数都不超过原来的一半多。思路
随便选定一个点作为根节点,建一颗树,同时记录下以当前点为根的树一共有多少节点,每次判断时判断每一个子节点是否超过一半,并判断其他的节点的总数是否超过一半即可#include <stdio.h> #include <queue> using namespace std; #define maxn 100001 struct edge { int to, next; }e[maxn]; int ls[maxn], f[maxn]; int fl[maxn], v = 0 , tot = 0; edge e2[maxn]; int ls2[maxn], s[maxn], xx[maxn], n; int check(int x) { for (int i = ls2[x]; i; i = e2[i].next) { if (s[e2[i].to] > n / 2) return 0; } return 1; } int ll = 0; int dfs1(int now, int fa) { fl[now] = 1; s[now] = 1; for (int i = ls[now]; i; i = e[i].next) if (fl[e[i].to] == 0) { e2[++ll] = (edge) {e[i].to, ls2[now]}; ls2[now] = ll; dfs1(e[i].to, now); s[now] += s[e[i].to]; } } int main() { scanf("%d", &n); int l = 0; for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); e[++l] = (edge) {y, ls[x]}; ls[x] = l; e[++l] = (edge) {x, ls[y]}; ls[y] = l; } dfs1(1, 0); for (int i = 1; i <= n; i++) { if (check(i) && n - s[i] <= n / 2) xx[i] = 1; } for (int i = 1; i <= n; i++) if (xx[i]) printf("%d\n", i); }
相关文章推荐
- jzoj1301 treecut
- jzoj. 1301. treecut
- [dfs序][线段树][并查集] JZOJ P3766 大融合
- JZOJ 7.9 B组第三题 treecut
- [jzoj1016][poj3321]苹果树(dfs序+树状数组维护)
- [并查集][排序][dfs][启发式合并] JZOJ P3635 Peaks
- jzoj P3769 A+B___dfs+规律
- jzoj3450【NOIP2013模拟联考3】山峰(summits,dfs)
- jzoj P1752 无聊的草稿___dfs+树的最长链
- [二分][dfs]JZOJ 2748 最大立方体空间 80%做法
- [jzoj]3511. 【NOIP2013模拟11.5A组】cza的蛋糕(cake)(DP嵌套dfs【快】或DP【慢】)
- 【汕头市选2014】分叉 jzoj 3630 dfs
- jzoj5336 【NOIP2017提高A组模拟8.24】提米树 (dfs序dp,奇异姿势dp)
- JZOJ4753【GDOI2017模拟9.4】种树 LCT维护子树信息+换根时维护Dfs序(CC MONOPLOY加强版)
- poj3984(DFS写法) 迷宫路径问题
- Posts Tagged 【list && tree && dfs】Flatten Binary Tree to Linked List
- Poj 3009 Curling 2.0【Dfs】
- 【JZOJ3222】【HNOI2013】切糕
- HDU 1016:Prime Ring Problem(基础DFS)
- uva 301 Transportation 铁路公司的阳谋 纯dfs暴力