POJ 2378 Tree Cutting (树的重心,微变形)

题意:

  给定一棵树,n个节点,若删除点v使得剩下的连通快最大都不超过n/2,则称这样的点满足要求。求所有这样的点,若没有这样的点,输出NONE。

思路:

  只需要拿“求树的重心”的代码改一行就OK了。因为依然是在判别最大连通块的点数。

 1 //#include <bits/stdc++.h>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <map>
 7 #include <deque>
 8 #include <algorithm>
 9 #include <vector>
10 #include <iostream>
11 #define pii pair<int,int>
12 #define max(x,y) ((x)>(y)?(x):(y))
13 #define min(x,y) ((x)<(y)?(x):(y))
14 #define INF 0x7f7f7f7f
15 #define LL  long long
16 using namespace std;
17 const double PI  = acos(-1.0);
18 const int N=10010;
19 int n,  edge_cnt, head[N];
20
21 struct node
22 {
23     int from, to, next;
24     node(){};
25     node(int from,int to,int next):from(from),to(to),next(next){};
26 }edge[N*2];
27
28 void add_node(int from,int to)
29 {
30     edge[edge_cnt]=node(from,to,head[from]);
31     head[from]=edge_cnt++;
32 }
33 deque<int> que;
34
35 int DFS(int t,int far)
36 {
37     node e;
38     int big=0, sum=0;
39     for(int i=head[t]; i!=-1; i=e.next)
40     {
41         e=edge[i];
42         if(e.to==far)   continue;
43
44         int tmp=DFS(e.to, t);
45         big=max(big, tmp);
46         sum+=tmp;
47     }
48     big=max(big, n-sum-1);
49
50     if(big<=n/2)    que.push_back(t);//只改这处地方
51     return sum+1;
52 }
53
54 int main()
55 {
56     //freopen("input.txt", "r", stdin);
57     int a, b;
58     while(~scanf("%d",&n))
59     {
60         edge_cnt=0;
61         memset(head,-1,sizeof(head));
62
63         for(int i=1; i<n; i++)
64         {
65             scanf("%d%d",&a,&b);
66             add_node(a,b);
67             add_node(b,a);
68         }
69         DFS(1,-1);
70         sort(que.begin(),que.end());
71         if(que.empty()) puts("NONE");
72         else
73         {
74             while(!que.empty())
75             {
76                 printf("%d\n",que.front());
77                 que.pop_front();
78             }
79         }
80     }
81     return 0;
82 }

AC代码

时间: 2024-10-01 03:40:51

POJ 2378 Tree Cutting (树的重心,微变形)的相关文章

POJ 2378 Tree Cutting (DFS)

题目链接:http://poj.org/problem?id=2378 一棵树,去掉一个点剩下的每棵子树节点数不超过n/2.问有哪些这样的点,并按照顺序输出. dfs回溯即可. 1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include &l

poj 2378 Tree Cutting (树形dp)

Tree Cutting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3910   Accepted: 2347 Description After Farmer John realized that Bessie had installed a "tree-shaped" network among his N (1 <= N <= 10,000) barns at an incredible

POJ 2378 Tree Cutting 子树统计

题目大意:给出一棵树,将树中的一个节点去掉之后,这棵树会分裂成一些联通块,求去掉哪些点之后,所有联通块的大小不超过所有节点的一半,并按顺序输出. 思路:基础的子树统计问题,只要深搜一遍就可以出解.这个步骤和求树的重心很像,是树分治的基础. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 10010 using nam

POJ 2378 Tree Cutting(树的重心)

题目链接:http://poj.org/problem?id=2378 题目: Description After Farmer John realized that Bessie had installed a "tree-shaped" network among his N (1 <= N <= 10,000) barns at an incredible cost, he sued Bessie to mitigate his losses. Bessie, fee

poj 1741 Tree(树的点分治)

poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出来.接着对于每一个子树再次运算.如果不用点分治的技巧,时间复杂度可能退化成\(O(n^2)\)(链).如果对于子树重新选根,找到树的重心,就一定可以保证时间复杂度在\(O(nlogn)\)内. 具体技巧是:首先选出树的重心,将重心视为根.接着计算出每个结点的深度,以此统计答案.由于子树中可能出现重复

POJ 1655 Balancing Act 树的重心 基础题

Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10347   Accepted: 4285 Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or m

POJ 1655 Balancing Act[树的重心/树形dp]

Balancing Act 时限:1000ms Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the largest tree

POJ 1655 Balancing Act (树的重心)

题目地址:POJ 1655 树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡. 树的重心可以用树形DP快速的找出来. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h>

POJ 3723 Tree(树链剖分)

POJ 3237 Tree 题目链接 就多一个取负操作,所以线段树结点就把最大和最小值存下来,每次取负的时候,最大和最小值取负后,交换即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 10005; const int INF = 0x3f3f3f3f; int dep[N],