2019ICPC徐州站M题

前天在复现赛开M自闭两天,全网找不到题解,后来偶遇cometoj群中的Acmer帮我解决困惑,在此匿名感谢qq名称为不好好学习不改名同学,以下思路均由他提供,也希望为后来人提供一定的思路和想法

题解: 首先很容易看出这是道求树的重心的问题,但是由于他要求所有子树的重心,所以暴力求解会超时,因此我们需要进行剪枝,剪枝需要几点性质

1.两个树合并之后树的重心在之前两棵树重心的连线路径上。

2.如果子树的节点数大于父树节点树的一半,那么父树重心可以由该子树转移而来,因为重心的意义就是代表除去该点后最大联通子树的节点数的最小值,所以我们把子树的节点数*2-父树的节点数作为贡献度,大于0就能转移。

然后就能做啦,注意的一点是,一棵树有可能有两个重心,两个重心必定相邻,因此只需要考虑当贡献度为0的时候就是两个答案。

复杂度因为我并不擅长求复杂度,但是据说是O(N)的

代码如下,代码中也有注释:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<functional>
#include<string>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#include<queue>
using namespace std;
const int N=4*1e5+10;
const int inf=0x3f3f3f3f;
int e[N],ne[N],idx;
int h[N];
int res[N];
int res1[N];
int size[N];
int p[N];
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int fa){
    size[u]=1;//初始个数为0
    res[u]=u;//初始化节点重心为自身,因为如果不能从子树重心转移过来,那这个树的重心就是自己
    int son=0;
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
        continue;
        p[j]=u;//j的父亲是u
        dfs(j,u);
        size[u]+=size[j];//计算节点总数
        if(size[j]>size[son])// 计算哪个是重(zhong)子树
        son=j;
    }
    // 如果符合条件就转移
    if(size[son]*2-size[u]>=0){
        res[u]=res[son];
        while(size[u]-2*size[res[u]]>0)
        res[u]=p[res[u]];  //通过迭代的方式往上走一格
        if(size[u]==2*size[res[u]]&&res[u]!=u){
            res1[u]=p[res[u]];
        }
    }
}
int main(){
    int m,n;
    cin>>n;
    int i;
    memset(h,-1,sizeof h);
    for(i=0;i<n-1;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
    }
    p[1]=1;
    dfs(1,-1);
    for (int i = 1; i <= n; i ++){

        if(!res1[i])
        printf("%d ", min(res1[i], res[i]);
        printf("%d\n", max(res1[i], res[i]);
    }

}

原文地址:https://www.cnblogs.com/ctyakwf/p/12010370.html

时间: 2024-08-30 18:33:50

2019ICPC徐州站M题的相关文章

2019ICPC徐州站题解

C题大水题,欧拉筛筛下素数,然后在线处理一下普通素数. 1 #include <bits/stdc++.h> 2 #define ll long long 3 #define scan(i) scanf("%d",&i) 4 #define scanl(i) scanf("%lld",&i) 5 #define scand(i) scanf("%lf",&i) 6 #define pf printf 7 #de

2019ICPC网赛南京站B题 super_log(欧拉降幂

https://nanti.jisuanke.com/t/41299 题意:让算a^(a^(a^(...))),一共b个a, (mod p)的结果. 思路:这是个幂塔函数,用欧拉降幂公式递归求解. #include<bits/stdc++.h> #define ll long long using namespace std; map<int,int> euler; ll a,b,mod; int phi(int n) { int now=n; int ret=n; if(eule

2016 ICPC青岛站---k题 Finding Hotels(K-D树)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5992 Problem Description There are N hotels all over the world. Each hotel has a location and a price. M guests want to find a hotel with an acceptable price and a minimum distance from their locations.

hdu 5077 NAND(打表)2014 Asia regional 鞍山站 H题

题目链接:点击打开链接 题意:就是一个按位运算的一个函数,问最少经过多少步运算可以得到给定数: 思路:不是我投机取巧想打表,是特么这题只能打表...打表思想用可以得到的数的集合表示状态bfs:最后有一个需要11步的需要打将近1h,除去这一个十分钟就够了. cpp: #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <map> using

zoj 3822 Domination 概率dp 2014牡丹江站D题

Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headmaster of Marjar University. He is enthusiastic about chess and often plays chess with his friends. What's more, he bought a large decorative chessboar

2018ACM-ICPC焦作站E题Resistors in Parallel

Resistors in Parallel 题目: ACM-ICPC Jiaozuo Onsite 2018 题解:因为题目数据范围很大,所以猜测应该是一个区间一个固定的最小值.问题转换成了如何求某个最小值影响的区间.坤神一眼看出,应该通过素数求,因为一个数的因子有很多,但是所有的因子都可以通过该数的素因子推出来.比如6的因子有1 2 3 6,素因子有2 3,所以1=2^0*3^0,2=2^1*3^0,3=2^0*3^1,6=2^1*3^1.又因为并联电阻并联越多阻值越小,所以在某些数有相同的素

2018ACM-ICPC亚洲区域赛南京站I题Magic Potion(网络流)

http://codeforces.com/gym/101981/attachments 题意:有n个英雄,m个敌人,k瓶药剂,给出每个英雄可以消灭的敌人的编号.每个英雄只能消灭一个敌人,但每个英雄只能消灭一个敌人.现在有药剂,英雄喝了之后可以多消灭一个敌人,但每个英雄只能喝一瓶,问最多能消灭多少个敌人. 下午在实验室队内自己开训练,和JC大佬那队一起开的,当时JC大佬他们队开的J题,没有看I题,当我们队AC之后JC大佬才看了I题,听到他们说,这题就差直接把网络流三个字写在题目里了.确实非常明显

2019ICPC银川站 后记

考量到银川赛区的综合因素,赛前给队友立下flag 所以说啊 我们前四场都喊着保银争金,结果差一点金了,这场喊着保金冲出线,结果差一点出线了(雾) 事实上从正式赛来看,本场也确实是我队建队以来发挥的最好,合作的最默契的现场赛了,自从上场哈尔滨去世导致我队被银牌四杀之后,我们就一直试图从队内配合,队内交流,现场赛环境差异来寻找问题,在总结了很多次之后,本场比赛,至少我们没有犯下肉眼可见的大错误--除了A题最后题意交流出错,但我们当时似乎也没有想到A题的正解 Day0: 队友叫我一起下棋,下了几把发现

2019icpc银川站 复现赛

打了计蒜客上的银川重现赛,总体感觉难度上确实比平时区域赛要低上一些. 这里补一下F题和G题的思路和代码. F题        做法,玩一下n=10的样例就出来啦! 解释:显然a^x的反函数为logax,我们先固定外层的求和的a,然后看内层求和的b,b从a开始加到n,注意到对于后半个向上取整的logba,b>=a,所以始终都是1,而对于前半个式子,只有当b经过a^i时才增加,举个例子就是log22~log23向下取整都为1,log24~log27向下取整都为2,log28~log210都为3. 对