bzoj1776
点分治/贪心
对于点分治的理解不够深刻...点分治能统计树上每个点对的信息,那么这里就是统计同种颜色点对之间的最大距离,自然可以用点分
然后点分,每次统计最大距离,但是略微卡常...
还有一种贪心的方法,每种颜色必然选以某点为根最深的节点,计算出最深的节点,然后dfs,看每种颜色,然后和最深的节点计算距离
#include<bits/stdc++.h>
using namespace std;
const int N = ;
int n, top, root, k, top1;
vector<int> G[N];
int size[N], mx[N], mark[N], ans[N], st[N], st1[N], c[N], a[N], mx_deep[N], now_deep[N], vis[N], vis1[N];
namespace IO
{
const int Maxlen = N * ;
char buf[Maxlen], *C = buf;
int Len;
inline void read_in()
{
Len = fread(C, , Maxlen, stdin);
buf[Len] = '\0';
}
inline void fread(int &x)
{
x = ;
int f = ;
while (*C < '' || '' < *C) { if(*C == '-') f = -; ++C; }
while ('' <= *C && *C <= '') x = (x << ) + (x << ) + *C - '', ++C;
x *= f;
}
inline void read(int &x)
{
x = ;
int f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << ) + (x << ) + c - ''; c = getchar(); }
x *= f;
}
inline void read(long long &x)
{
x = ;
long long f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << 1ll) + (x << 3ll) + c - ''; c = getchar(); }
x *= f;
}
} using namespace IO;
void findroot(int u, int last, int tot)
{
size[u] = ;
mx[u] = ;
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(v == last || mark[v]) continue;
findroot(v, u, tot);
size[u] += size[v];
if(size[v] > mx[u]) mx[u] = size[v];
}
mx[u] = max(mx[u], tot - mx[u]);
if(mx[u] < mx[root]) root = u;
}
void dfs(int u, int last, int deep)
{
if(mx_deep[a[u]] == -) st[++top] = a[u];
mx_deep[a[u]] = max(mx_deep[a[u]], deep);
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(v == last || mark[v]) continue;
dfs(v, u, deep + );
}
}
int get_size(int u, int last)
{
int ret = ;
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(v == last || mark[v]) continue;
ret += get_size(v, u);
}
return ret;
}
void divide(int u)
{
root = ;
findroot(u, , get_size(u, ));
mark[root] = ;
now_deep[a[root]] = ;
st1[++top1] = a[root];
for(int i = ; i < G[root].size(); ++i)
{
int v = G[root][i];
if(mark[v]) continue;
dfs(v, root, );
if(mx_deep[a[root]] == -) st[++top] = a[root], mx_deep[a[root]] = ;
for(int j = top; j; --j) if(now_deep[st[j]] != -) ans[st[j]] = max(ans[st[j]], now_deep[st[j]] + mx_deep[st[j]]);
while(top)
{
if(now_deep[st[top]] == -) st1[++top1] = st[top];
now_deep[st[top]] = max(now_deep[st[top]], mx_deep[st[top]]);
mx_deep[st[top--]] = -;
}
}
while(top1) now_deep[st1[top1--]] = -;
for(int i = , now = root; i < G[now].size(); ++i)
{
int v = G[now][i];
if(mark[v]) continue;
divide(v);
}
}
int main()
{
memset(now_deep, -, sizeof(now_deep));
memset(mx_deep, -, sizeof(mx_deep));
read_in();
fread(n);
fread(k);
for(int i = ; i <= n; ++i)
{
int u;
fread(a[i]);
fread(u);
if(u) { G[u].push_back(i); G[i].push_back(u); }
}
mx[] = << ;
divide();
for(int i = ; i <= k; ++i) printf("%d\n", ans[i]);
return ;
}
bzoj1776的更多相关文章
- 【BZOJ1776】[Usaco2010 Hol]cowpol 奶牛政坛 树的直径
[BZOJ1776][Usaco2010 Hol]cowpol 奶牛政坛 Description 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N. ...
- [BZOJ1776][Usaco2010 Hol]cowpol 奶牛政坛
Description 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地.而且从每片 ...
- [bzoj1776][Usaco2010 Hol]cowpol 奶牛政坛_倍增lca
[Usaco2010 Hol]cowpol 奶牛政坛 题目大意: 数据范围:如题面. 题解: 第一想法是一个复杂度踩标程的算法..... 就是每种政党建一棵虚树,然后对于每棵虚树都暴力求直径就好了,复 ...
- 【刷题记录】BZOJ-USACO
接下来要滚去bzoj刷usaco的题目辣=v=在博客记录一下刷题情况,以及存一存代码咯.加油! 1.[bzoj1597][Usaco2008 Mar]土地购买 #include<cstdio&g ...
随机推荐
- 15Spring AOP基础
为什么需要AOP? 先来看一段代码: package com.cn.spring.aop.helloworld; //加减乘除的接口类 public interface ArithmeticCalcu ...
- eclipse导入项目时报错不能运行问题的一个记录
一直用学校的云桌面,但是还是有一些地方不是很方便,必须要校园网以及需要离线保存: 碰到的问题:重新安装和云桌面一样版本的jdk9.0.4,以及tomcat9.0.12,以及eclipse-oxygen ...
- UVA 221 城市化地图(离散化思想)
题意: 给出若干个栋楼俯视图的坐标和面积,求从俯视图的南面(可以视为正视图)看过去到底能看到多少栋楼. 输入第一个n说明有n栋楼,然后输入5个实数(注意是实数),分别是楼的左下角坐标(x,y), 然后 ...
- Jquery 引擎模板 -template详解
一.1.jTemplate简介 jTemplates是一个基于Jquery的js模板引擎插件.该引擎全部代码由JS实现,可以配合AJAX,JSON一起协同工作,模板内容可以用JS代码,实现了活动更新, ...
- eclipse中自动生成注释
eclipse中自动生成注释 包前缀设置的地方 注释模板设置的地方 Eclipse自动生成方法注释 快捷键 自动生成方法的注释格式,例如 /*** @param str* @return* @thro ...
- BFS简单迷宫
常见迷宫: 输入迷宫 启点 终点 然后求最短路径 BFS例题 用dist[][]数组来记录 启点到每个点的最短路径 #include <iostream> #include <fst ...
- codevs 3971 航班
题目描述 Description B 国有N 座城市,其中1 号是这座国家的首都. N 座城市之间有M 趟双向航班.i 号点的转机次数定义为:从1 号点到i ,最少需要转机几 次.如果1 根本无法到达 ...
- HashMap的工作原理以及代码实现,为什么要转换成红黑树?
原理参考:https://blog.csdn.net/striveb/article/details/84657326 总结: 为什么当桶中键值对数量大于8才转换成红黑树,数量小于6才转换成链表? 参 ...
- NOIP 2009 潜伏者
P1071 潜伏者 题目描述 RR 国和 SS 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动.历尽艰险后,潜伏于 SS 国的 RR 国间谍小 CC 终于摸清了 SS 国军用密码的编码规则: ...
- mysql的时间戳说白了就俩问题,自动更新问题和不自动更新问题
mysql的时间戳timestamp说白了就俩问题,自动更新问题和不自动更新问题