首页 > 代码库 > AIM Tech R3 div2 E Centroid
AIM Tech R3 div2 E Centroid
思路很明显了,假设是点x,则看它的子树中是否有大于n/2的,如果有,则在该子树中剪去它可以剪的且小于n/2的,接到点x上。
则统计出在以x点为根的子树中,它的各子树可以剪去的且小于n/2的最大子子树。对于除去以x为根的子树的其他部分,记为up,则同样地统计它的可以剪除的符合条件的子树,最后对每个点判断一下就可以了。
代码如下::(额,想的时候对up的这个不知道怎么写~谢指导)
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>//#include <bitset>using namespace std;const int MAXN = 400010;vector<int> t[MAXN];int par[MAXN], sz[MAXN], up[MAXN], dw[MAXN], n;void dfs_sz(int u, int parent){ par[u] = parent; sz[u] = 1; int size = t[u].size(); for(int i = 0; i< size; i++){ int v = t[u][i]; if(v == parent) continue; dfs_sz(v, u); sz[u] += sz[v]; }}void dfs_down(int u, int parent){ dw[u] = (sz[u] <= n/2 ? sz[u] : 0); int size = t[u].size(); for(int i = 0; i < size; i++){ int v = t[u][i]; if(v == parent) continue; dfs_down(v, u); dw[u] = max(dw[u], dw[v]); }}void dfs_up(int u, int parent, int val){ up[u] = max((n - sz[u] <= n /2? n - sz[u]: 0), val); int size = t[u].size(); int mx0 = 0, mx1 = 0; for(int i = 0; i < size; i++){ int v = t[u][i]; if(v == parent) continue; if(dw[v] >= mx0){ mx1 = mx0; mx0 = dw[v]; } else if(dw[v] >= mx1){ mx1 = dw[v]; } } for(int i = 0; i < size ; i++){ int v = t[u][i]; if(v == parent) continue; dfs_up(v, u, max(up[u], (mx0 == dw[v]? mx1 : mx0 ))); } }int main(){ int u, v; scanf("%d", &n); for(int i = 1; i< n; i++){ scanf("%d%d", &u, &v); t[u].push_back(v); t[v].push_back(u); } dfs_sz(1, -1); dfs_down(1, -1); dfs_up(1, -1, 0); for(int i = 1; i <= n; i++){ int ans = 1; int size = t[i].size(); for(int k = 0; k < size; k++){ int u = t[i][k]; if(u == par[i]){ if(n - sz[i] - up[i] > n/2) ans = 0; } else { if(sz[u] - dw[u] > n/ 2) ans = 0; } } printf("%d", ans); if(i == n) printf("\n"); else printf(" "); } return 0;}
AIM Tech R3 div2 E Centroid
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。