http://codeforces.com/contest/734/problem/E

看了题解,缩点 + 树的直径。

然而一直wa14.

注意到,

缩点后重建图,在5的时候,5和6建了一条边,然后6的时候,又和5建一次边。这个时候就要大数组了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = * + ;
int first[maxn];
int first_sec[maxn];
int num, num_sec;
struct node {
int u, v, w;
int tonext;
}e[maxn * ], e_sec[maxn * ];
int col[maxn];
void add(int u, int v) {
++num;
e[num].u = u;
e[num].v = v;
e[num].tonext = first[u];
first[u] = num;
}
void add_sec(int u, int v) {
++num_sec;
e_sec[num_sec].u = u;
e_sec[num_sec].v = v;
e_sec[num_sec].tonext = first_sec[u];
first_sec[u] = num_sec;
}
bool vis[maxn];
int fa[maxn];
int find(int u) {
if (u == fa[u]) return u;
else return fa[u] = find(fa[u]);
}
void merge(int u, int v) {
u = find(u);
v = find(v);
if (u != v) {
fa[v] = u;
}
}
void dfs(int cur) {
for (int i = first[cur]; i; i = e[i].tonext) {
int v = e[i].v;
if (vis[v]) continue;
vis[v] = true;
if (col[cur] == col[v]) {
merge(cur, v);
}
dfs(v);
}
}
void dfs2(int cur) {
printf("cur %d : %d\n", cur, col[cur]);
for (int i = first_sec[cur]; i; i = e_sec[i].tonext) {
int v = e_sec[i].v;
if (vis[v]) continue;
vis[v] = true;
dfs2(v);
}
}
struct NODE {
int cur, cnt;
NODE(int aa, int bb) : cur(aa), cnt(bb) {}
};
int bfs(int begin) {
memset(vis, , sizeof vis);
queue<struct NODE>que;
while(!que.empty()) que.pop();
que.push(NODE(begin, ));
vis[begin] = true;
int mx = -inf;
int to = begin;
while (!que.empty()) {
struct NODE t = que.front();
que.pop();
for (int i = first_sec[t.cur]; i; i = e_sec[i].tonext) {
int v = e_sec[i].v;
if (vis[v]) continue;
que.push(NODE(v, t.cnt + ));
vis[v] = true;
if (mx < t.cnt + ) {
mx = t.cnt + ;
to = v;
}
}
}
if (to == begin) return ;
// cout << to << " " << mx << endl;
que.push(NODE(to, ));
memset(vis, , sizeof vis);
vis[to] = true;
mx = -inf;
to = ;
while (!que.empty()) {
struct NODE t = que.front();
que.pop();
for (int i = first_sec[t.cur]; i; i = e_sec[i].tonext) {
int v = e_sec[i].v;
if (vis[v]) continue;
que.push(NODE(v, t.cnt + ));
if (mx < t.cnt + ) {
mx = t.cnt + ;
to = v;
}
vis[v] = true;
}
}
// cout << mx << " " << to << endl;
return mx;
}
void work() {
int n;
scanf("%d", &n);
for (int i = ; i <= n; ++i) fa[i] = i;
for (int i = ; i <= n; ++i) scanf("%d", &col[i]);
for (int i = ; i <= n - ; ++i) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
if (num > * ) while();
}
vis[] = true;
dfs();
// for (int i = 1; i <= n; ++i) {
// printf("%d\n", find(i));
// }
for (int i = ; i <= n; ++i) {
for (int j = first[i]; j; j = e[j].tonext) {
int v = e[j].v;
if (find(i) == find(v)) continue;
// printf("%d %d\n", find(i), find(v));
// printf("fff");
add_sec(find(i), find(v));
add_sec(find(v), find(i));
}
}
// memset(vis, 0, sizeof vis);
// vis[1] = 1;
// dfs2(1);
int ans = bfs(find());
cout << (ans + ) / << endl;
} int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
work();
return ;
}

为什么直径 /  2是答案?因为可以在直径中间的那个点,一直变一直变。

E. Anton and Tree 数组开大点的更多相关文章

  1. [ACM_数据结构] Color the ball [线段树水题][数组开大]

    Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次 ...

  2. Atitit 编程语言知识点tech tree v2 attilax大总结

    Atitit 编程语言知识点tech tree v2 attilax大总结 大分类中分类小分类知识点原理与规范具体实现(javac#里面的实现phpjsdsl(自己实现其他语言实现 类与对象实现对象实 ...

  3. Codeforces Round #379 (Div. 2) E. Anton and Tree —— 缩点 + 树上最长路

    题目链接:http://codeforces.com/contest/734/problem/E E. Anton and Tree time limit per test 3 seconds mem ...

  4. Codeforces 734E. Anton and Tree 搜索

    E. Anton and Tree time limit per test: 3 seconds memory limit per test :256 megabytes input:standard ...

  5. Codeforces Round #379 (Div. 2) E. Anton and Tree 缩点 直径

    E. Anton and Tree 题目连接: http://codeforces.com/contest/734/problem/E Description Anton is growing a t ...

  6. Codeforces Round #379 (Div. 2) E. Anton and Tree 树的直径

    E. Anton and Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard i ...

  7. 开大Stack的一个小技巧

    在程序头部添加一行 #pragma comment(linker, "/STACK:16777216") 可有效开大堆栈 实验效果如下: 11330179 2014-08-05 1 ...

  8. Anton and Tree

    Anton and Tree 题目链接:http://codeforces.com/contest/734/problem/E DFS/BFS 每一次操作都可以使连通的结点变色,所以可以将连通的点缩成 ...

  9. Codeforces 734E Anton and Tree(缩点+树的直径)

    题目链接: Anton and Tree 题意:给出一棵树由0和1构成,一次操作可以将树上一块相同的数字转换为另一个(0->1 , 1->0),求最少几次操作可以把这棵数转化为只有一个数字 ...

随机推荐

  1. group by where having 联合使用

    having子句与where有相似之处但也有区别,都是设定条件的语句.在查询过程中聚合语句(sum,min,max,avg,count)要比having子句优先执行.而where子句在查询过程中执行优 ...

  2. Java代理(Aop实现的原理)

    经过大牛同事的一句指点立马明确的代理实现方式,Spring Aop应该也是这么去做的.直接上代码 实如今Car的run方法之前调用star方法,在run方法之后调用stop方法. Car类 packa ...

  3. sql语句,无法绑定由多个部分组成的标识符 "xxx"

    String sql = "select TOP 7 news_id,news_title,news_addtime,news_url from web_news_info a" ...

  4. redis09---redis 服务器端命令

    redis 服务器端命令 db0,db1,db2是数据库,外层是服务器,服务器下面有20个数据库. :>time ) "" //多少秒 ) "" //多少 ...

  5. (C)非局部跳转语句(setjmp和longjmp)

    1. 特点 非goto语句在函数内实施跳转,而是在栈上跳过若干调用帧,返回到当前函数调用路径上的某一语句. 头文件包含#include Void longjmp(jmp_buf env,int val ...

  6. webpack与grunt/glub 的比较

    webpack.grunt.glub 都是前端打包的工具: grunt/gulp 的工作方式是:在一个配置文件中,指明对某些文件进行压缩.组合.检查等任务的具体步骤,然后在运行中输入相应的命令. we ...

  7. LightOJ - 1422 Halloween Costumes —— 区间DP

    题目链接:https://vjudge.net/problem/LightOJ-1422 1422 - Halloween Costumes    PDF (English) Statistics F ...

  8. YTU 2481: 01字串

    2481: 01字串 时间限制: 1 Sec  内存限制: 128 MB 提交: 103  解决: 72 题目描述 对于长度为7位的一个01串,每一位都可能是0或1,一共有128种可能.它们的前几个是 ...

  9. asp+jQuery解决中文乱码

    1. [代码][ASP/Basic]代码 '在客户端使用javascript的escape()方法对数据进行编码,在服务器端使用对等的VbsUnEscape()对数据进行解码,同样在服务器端使用Vbs ...

  10. centos7更改远程端口

    centos7更改远程端口 一.创建个普通账户(useradd work),给普通账户创建密码(password work) 二.查看应有的软件是否安装 1.查看semanager是否安装执行下面命令 ...