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 ...
随机推荐
- java中的代码块执行顺序
/* 代码块:在Java中,使用{}括起来的代码被称为代码块. 根据其位置和声明的不同,可以分为 局部代码块:局部位置,用于限定变量的生命周期. 构造代码块:在类中的成员位置,用{}括起来的代码.每次 ...
- ArrayList集合
//在使用ArrayList时别忘了引用命名空间 using System.Collections;//首先得导入命名空间 //01.添加方法 add方法 //告诉内存,我要存储内容 ArrayLis ...
- Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (一) —— 总览
Android数据的四种存储方式SharedPreferences.SQLite.Content Provider和File (一) —— 总览 作为一个完成的应用程序,数据存储操作是必不可少的. ...
- js argument实参集合与局部变量、参数关系
形参 形式上传递的参数 function fn1(a,b,c) {//a,b,c就是形参 实参 实际传递的参数 fn1 (1,2,5);//1,2,5就是实参 argument 定义: 实参的集合 用 ...
- Android Studio用release模式进行调试
有时候调试SDK必须要用release版本,但是每次打包混淆太麻烦,希望能在IDE中直接跑出release版本的应用,简单来说就是在debug模式下产生release版本的app,这时候该怎么做呢?当 ...
- File类的常用方法
public static void GetFileInfo() { File file=new File("e:","two.txt ...
- Animated progress view with CAGradientLayer(带翻译)<待更新>
原文网址:使用CAGradientLayer的动画精度条View Modern software design is getting flatter and thinner all the time. ...
- 【SVN】Unable to connect to a repository at URL 'svn://localhost/Test'
早上配置SVN,但是这次不是那么顺利... 环境: Windows 7 SVN服务器端:CollabNetSubversion-server-1.8.13-1 SVN客户端:TortoiseSVN_V ...
- 5+ App开发入门指南
HTML5 Plus应用概述 HTML5 Plus移动App,简称5+App,是一种基于HTML.JS.CSS编写的运行于手机端的App,这种App可以通过扩展的JS API任意调用手机的原生能力,实 ...
- 【JavaScript】JQuery中$.fn、$.extend、$.fn.extend
Web开发肯定要使用第三方插件,对于一个炫丽的效果都忍不住想看看对方是如何实现的,刚下载了一个仿京东商品鼠标经过时局部放大的插件.看了两眼JQuery源码,看看就感觉一头雾水.JQuery本来自己学的 ...