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 ...
随机推荐
- Rightmost Digit (求n^n最后一位)
Description Given a positive integer N, you should output the most right digit of N^N. Input The ...
- matplotlib多种绘图方式
目录 散点图 条形图 直方图 总结 散点图 假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温和随时间(天)变化的某种规律? a = [1 ...
- 从PDF复制到word(换行问题)
当我们从pdf文档中复制一部分内容到word的时候,pdf的自动换行会自动给文字添加换行,也就是一个回车,让文字另起一行,这样粘贴到word中的时候,word中也会有很多换行符,排版比较麻烦,需要一个 ...
- C51 原创电子琴 (蜂鸣器/计时器/中断/矩阵按键)
需求分析 用C51的16个矩阵按键当作两个八度的琴键 按下时发出相应音调的声音,静态数码管显示相应音符的数字. 为了解锁更多曲目,两个多的琴键设计成#4,显示时加上小数点 下图分别为1和#4的显示,其 ...
- openjudge6252 带通配符的字符串匹配
描述 通配符是一类键盘字符,当我们不知道真正字符或者不想键入完整名字时,常常使用通配符代替一个或多个真正字符.通配符有问号(?)和星号(*)等,其中,“?”可以代替一个字符,而“*”可以代替零个或多个 ...
- 无法打开物理文件 "X.mdf"。操作系统错误 5:"5(拒绝访问。)"。 (Microsoft SQL Server,错误: 5120)解决
环境 SQLServer 2008 R2 问题 附加数据库出现“无法打开物理文件 "X.mdf".操作系统错误 5:"5(拒绝访问.)". (Microsoft ...
- hdu3756(三分)
题意:三维坐标轴,有以原点为圆心,底面在xoy平面上,顶点在z轴上的圆锥,问圆锥的最小体积为多少才能完全覆盖空间里的所有点(n<=10000) 分析: 很容易想到转成二维问题,将其投影到xoz平 ...
- CSS聊天气泡
概述 谷歌效果图如下: ie效果图如下: 完整代码 <!DOCTYPE html> <html> <head> <meta charset="gbk ...
- mysql数据类型和java数据类型匹配
Java数据类型和MySql数据类型对应一览 类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述 VARCHAR L+N VARCHAR java. ...
- Win10還原成最乾淨的狀態
系統不穩定時我們想到的第一個選擇就是重灌,如果你的作業系統是win10將會有另外一個新選擇,就是透過程式進行還原,讓你的電腦回到剛安裝時的清爽. 工具資訊 [軟體名稱]微軟 Refresh Windo ...