codeforces 709E E. Centroids(树形dp)
题目链接:
4 seconds
512 megabytes
standard input
standard output
Tree is a connected acyclic graph. Suppose you are given a tree consisting of n vertices. The vertex of this tree is called centroid if the size of each connected component that appears if this vertex is removed from the tree doesn't exceed
.
You are given a tree of size n and can perform no more than one edge replacement. Edge replacement is the operation of removing one edge from the tree (without deleting incident vertices) and inserting one new edge (without adding new vertices) in such a way that the graph remains a tree. For each vertex you have to determine if it's possible to make it centroid by performing no more than one edge replacement.
The first line of the input contains an integer n (2 ≤ n ≤ 400 000) — the number of vertices in the tree. Each of the next n - 1 lines contains a pair of vertex indices ui and vi (1 ≤ ui, vi ≤ n) — endpoints of the corresponding edge.
Print n integers. The i-th of them should be equal to 1 if the i-th vertex can be made centroid by replacing no more than one edge, and should be equal to 0 otherwise.
3
1 2
2 3
1 1 1
5
1 2
1 3
1 4
1 5
1 0 0 0 0 题意: 给出一棵树,要求你最多改变一条边,看这个点能否成为重心; 思路: 树形dp,先转化成有根树,第一次dfs先找到每个节点以下的节点数目和能切断的最多的数目以及最多和次多转移来的节点,第二次dfs就是找答案了;
由于一个那个超过n/2的子树只有一棵,要么来自当前节点的子节点,要么来自父节点,所以在树上进行转移;具体的看代码注释; AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>
#include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=4e5+10;
const int maxn=1e3+20;
const double eps=1e-12; int n,siz[N],ans[N],submax[N],max1[N],max2[N];
vector<int>ve[N]; void dfs(int cur,int fa)
{
siz[cur]=1;//节点数目
submax[cur]=0;//submax[cur]是以cur为根的子树能切掉的最大的节点数目,
int len=ve[cur].size();
for(int i=0;i<len;i++)
{
int x=ve[cur][i];
if(x==fa)continue;
dfs(x,cur);
siz[cur]+=siz[x];
if(submax[x]>submax[cur])
{
max2[cur]=max1[cur];//max2[cur]记录次大,max1[cur]记录最大;
max1[cur]=x;
submax[cur]=submax[x];
}
else if(submax[x]>submax[max2[cur]])max2[cur]=x;
}
if(siz[cur]<=n/2)submax[cur]=siz[cur];
}
void dfs1(int cur,int fa,int mmax)
{
int len=ve[cur].size(),flag=1;
for(int i=0;i<len;i++)
{
int x=ve[cur][i];
if(x==fa)//父节点转移过来
{
int temp=n-siz[cur];
if(temp>n/2&&temp-mmax>n/2)flag=0;
continue;
}
if(siz[x]>n/2)//子节点转移过来
{
if(siz[x]-submax[x]>n/2)flag=0;
}
}
ans[cur]=flag;
for(int i=0;i<len;i++)
{
int x=ve[cur][i];
if(x==fa)continue;
int temp;
if(n-siz[x]<=n/2)temp=n-siz[x];
else
{
if(max1[cur]==x)temp=max(mmax,submax[max2[cur]]);//如果x正好是最大的转移过来的就取mmax和次大的最大值
else temp=max(mmax,submax[max1[cur]]);//否则取mmax与最大的最大值
}
dfs1(x,cur,temp);
}
}
int main()
{
read(n);
int u,v;
For(i,1,n-1)
{
read(u);read(v);
ve[v].push_back(u);
ve[u].push_back(v);
}
dfs(1,0);
dfs1(1,0,0);
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
return 0;
}
codeforces 709E E. Centroids(树形dp)的更多相关文章
- codeforces 212E IT Restaurants(树形dp+背包思想)
题目链接:http://codeforces.com/problemset/problem/212/E 题目大意:给你一个无向树,现在用两种颜色去给这颗树上的节点染色.用(a,b)表示两种颜色分别染的 ...
- Codeforces 123E Maze(树形DP+期望)
[题目链接] http://codeforces.com/problemset/problem/123/E [题目大意] 给出一棵,给出从每个点出发的概率和以每个点为终点的概率,求出每次按照dfs序从 ...
- CodeForces 77C Beavermuncher-0xFF (树形dp)
不错的树形dp.一个结点能走多次,树形的最大特点是到达后继的路径是唯一的,那个如果一个结点无法往子结点走,那么子结点就不用考虑了. 有的结点不能走完它的子结点,而有的可能走完他的子节点以后还会剩下一些 ...
- bzoj 4424: Cf19E Fairy && codeforces 19E. Fairy【树形dp】
参考:https://blog.csdn.net/heheda_is_an_oier/article/details/51131641 这个找奇偶环的dp1真是巧妙,感觉像tarjan一样 首先分情况 ...
- Codeforces 709E. Centroids 树形DP
题目链接:http://codeforces.com/contest/709/problem/E 题意: 给你一棵树,你可以任删一条边和加一条边,只要使得其仍然是一棵树,输出每个点是否都能成为重心 题 ...
- Codeforces gym101955 A【树形dp】
LINK 有n个大号和m个小号 然后需要对这些号进行匹配,一个大号最多匹配2个小号 匹配条件是大号和小号构成了前缀关系 字符串长度不超过10 问方案数 思路 因为要构成前缀关系 所以就考虑在trie树 ...
- Educational Codeforces Round 52F(树形DP,VECTOR)
#include<bits/stdc++.h>using namespace std;int n,k;vector<int>son[1000007];int dp[100000 ...
- codeforces 696B B. Puzzles(树形dp+概率)
题目链接: B. Puzzles time limit per test 1 second memory limit per test 256 megabytes input standard inp ...
- Codeforces 490F Treeland Tour 树形dp
Treeland Tour 离散化之后, 每个节点维护上升链和下降链, 感觉复杂度有点高, 为啥跑这么快.. #include<bits/stdc++.h> #define LL long ...
随机推荐
- 使用jQuery库改造ajax
html页 ---------------------------------------------------------------------------------------------- ...
- 从Android系统出发,分析Android控件构架
从Android系统出发,分析Android控件构架 Android中所有的控件追溯到根源,就是View 和ViewGroup,相信这个大家都知道,但是大家也许会不太清楚它们之间的具体关系是什么,在A ...
- 调用另一个Activity
<转>调用另一个Activity Intent对象的使用 范例说明 前一个范例介绍了如何运用切换Layout的方式,进行手机页面间的转换.如果要转换的页面并不单只是背景.颜色或文字内容的不 ...
- OS X 在Cisco无线环境下丢包分析 part 1
补发一篇博客,之前遇到的没有写成博文的一个情况.我擦,那一阵儿真是被无线搞疯了. 现象:苹果OS X用户连入WiFi之后莫名丢包,而且有规律的丢,丢个5s恢复正常,再过会儿再丢5s左右. 就如同这样 ...
- 被混淆的C#类库的反编译
今天看公司以前的代码,用的是.NRT Reactor v4.4.7.5进行的混淆,直接使用.NET Reflector v8.5.0.179 是无法查看的,提示:Invalid number of d ...
- GetStartedWithWin10Develop
GetStartedWithWin10Develop 首先要确保已经配置好win10开发环境,开始第一个win10开发的HelloWorld 1.首先创建你的win10项目(示例的项目名称为 Hell ...
- bootstrap第一天,响应式布局,栅格系统运用
<!DOCTYPE html><html lang="zh-CN"> <head> <meta charset="utf-8&q ...
- Ettercap中间人攻击--介绍
前言 Ettercap有四种界面:Text,Curses,GTK2,Daemonize. -T 命令行界面,只显示字符.通常与配套的参数有-q(安静模式),加上该选项,则不会显示抓到的数据包 ...
- Windows2008系统忘记密码的解决方法
网上转载的,忘记密码不用发愁了. windows2008系统忘记密码的解决方法: 利用放大镜的漏洞来重设密码 首先用系统盘来引导 选择修复计算机 然后打开命令提示符:先备份放大镜,然后用CMD替换 ...
- 关于Activity销毁,而绘制UI的子线程未销毁出现的问题
项目总结 ----------------------------------------------------------------------------------------------- ...