标签:poj
题意:
给一棵n个节点连通的树
条件 : 去掉一个节点 使剩下的每个连通分量 都不超过n/2个节点
让找出所有符合上述条件的点 按照从小到大的顺序输出
思路:
首先建树
然后在建树的过程中,统计每个节点的子树中 最多的节点个数
同时统计以此结点为根的树的 节点总数 sum[i]
可以根据 n - sum[i] 算出上面一个祖先连通分量的节点个数
判断即可
code:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<queue> #include<map> #include<set> #include<cmath> using namespace std; #define INF 0x3f3f3f3f #define PI acos(-1.0) #define eps 1e-4 #define maxd 10e4 #define mem(a, b) memset(a, b, sizeof(a)) typedef pair<int,int> pii; typedef long long LL; //------------------------------ const int maxn = 10005; vector<int> g[maxn]; int n; int all[maxn], son[maxn]; int vis[maxn]; void init(){ int u,v; for(int i = 0; i < n-1; i++){ scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u); } } vector<int> ans; bool judge(int x){ if(son[x] <= n/2 && n - all[x] <= n/2) return true; return false; } int dfs(int u, int fa){ if(vis[u]) return all[u]; vis[u] = 1; int& ans1 = son[u]; int& ans2 = all[u]; ans1 = 0, ans2 = 1; for(int i = 0; i < g[u].size(); i++){ int v = g[u][i]; if(v == fa) continue; int tmp = dfs(v, u); ans1 = max(ans1, tmp); ans2 += tmp; } if(judge(u)) ans.push_back(u); return ans2; } void solve(){ memset(vis, 0, sizeof(vis)); dfs(1, 0); sort(ans.begin(), ans.end()); for(int i = 0; i < ans.size(); i++){ printf("%d\n",ans[i]); } } int main(){ scanf("%d",&n); init(); solve(); return 0; }
(思路写得太多了...)
树一类的题目,应该多考虑利用树的性质来解决问题
标签:poj
原文地址:http://blog.csdn.net/u013382399/article/details/45201365