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. XML复习笔记(复习资料为菜鸟教程里的XML教程)

    XML 指可扩展标记语言(eXtensible Markup Language) XML 的设计宗旨是传输数据,而不是显示数据. XML 标签没有被预定义.您需要自行定义标签. XML 被设计为具有自 ...

  2. CSS 媒体类型 总结

    CSS 媒体类型 媒体类型允许你指定文件将如何在不同媒体呈现.该文件可以以不同的方式显示在屏幕上,在纸张上,或听觉浏览器等等. 媒体类型 一些CSS属性只设计了某些媒体.例如"voice-f ...

  3. HttpServletRequestWrapper模拟实现分布式Session

    HttpSession的内容都放在一个单独的Map中,模拟远程分布式Session. 1.使用HttpServletRequestWrapper创建自定义Request2.使用动态代理包装自定义Req ...

  4. 注意css 小细节 颜色能缩写尽量缩写

    如 background: #333333; 改为 background: #333;

  5. (C)字节对齐#pragma pack()

    1. 为什么要进行对齐 对于结构体,编译器会自动进行成员变量对齐处理,是为了提高运算效率. 缺省情况下是自然对齐方式. 2. 自然对齐 即默认对齐,按照结构体的成员中size最大的成员进行对齐. 例: ...

  6. vue 移动端开发

    1.vue开发中的路由: 关于require 与import 的区别 2.vue中的mock数据 3.

  7. 构造方法,重载,static,math类(java基础知识七)

    1.构造方法概述和格式 * A:构造方法概述和作用     * 给对象的数据(属性)进行初始化 * B:构造方法格式特点     * a:方法名与类名相同(大小也要与类名一致)     * b:没有返 ...

  8. Oracle:热备时,突然断电情况处理

    我们在热备时,如果此时突然停电,再次启动时会发生什么情况呢? SQL> alter tablespace users begin backup; Tablespace altered. SQL& ...

  9. apache 安装及配置

    近期想用apache运行网站,在网上查询windows 版本的中文说明文档有特别少,所以将学习到的在这里做个笔记,以便日后学习以及大家相互交流. 相关文档:http://httpd.apache.or ...

  10. macbook pro 一些操作经验记录

    [一]启用root用户 (1)打开终端 (2)输入命令:sudo passwd root (3)给root设置密码 (4)然后再终端输入命令:su root 进行登陆 [二]解压eclipse压缩包, ...