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 ...
随机推荐
- list嵌套,int与str的用法,replace
#*************************replace(待改,改动值),返回很重要 A = [['libai',89]] A[0][0]=A[0][0].replace('a','af') ...
- (转载)O(N)的素数筛选法和欧拉函数
转自:http://blog.csdn.net/dream_you_to_life/article/details/43883367 作者:Sky丶Memory 1.一个数是否为质数的判定. 质数,只 ...
- vim 编辑器使用法则
vim 编辑器使用法则 Vi编辑器有3种使用模式:一般模式.编辑模式和命令模式. $SHELL:查看当前默认shell类型 $BASH_VERSION:查看当前shell版本 3.一般模式: 光标移 ...
- jquery对JSON字符串的解析--eval函数
jquery eval解析JSON中的注意点介绍----https://www.jb51.net/article/40842.htm
- xtu summer individual 6 D - Checkposts
Checkposts Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Orig ...
- [Zabbix] 如何实现邮件报警通知以及免费短信报警通知
版权声明:本文为博主原创文章,未经博主允许不得转载. 前提条件: (1) zabbix服务器端已经成功安装并且运行. (2) zabbix客户端已经成功建立并且运行. 1 下载并且安装msmtp软件 ...
- mariadb,maria db
mariadb,maria db 继续紧逼Oracle:在占领谷歌等公司之后,MariaDB迈向企业端 发表于2013-10-25 13:00|10618次阅读|10条评论 MariaDB在Googl ...
- MySQL Workbench基本操作
MySQL Workbench是一款专为MySQL设计的ER/数据库建模工具.它是著名的数据库设计工具DBDesigner4的继任者.你可以用MySQL Workbench设计和创建新的数据库图示,建 ...
- Arctic Network POJ - 2349
The Department of National Defence (DND) wishes to connect several northern outposts by a wireless n ...
- JVM(二):Java中的语法糖
JVM(二):Java中的语法糖 上文讲到在语义分析中会对Java中的语法糖进行解糖操作,因此本文就主要讲述一下Java中有哪些语法糖,每个语法糖在解糖过后的原始代码,以及这些语法糖背后的逻辑. 语法 ...