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. Robots协议应用与写法研究

  2. NBUT 1222 English Game(trie树+DP)

    [1222] English Game 时间限制: 1000 ms 内存限制: 131072 K 问题描写叙述 This English game is a simple English words ...

  3. Qt & opencv 学习(二)

    例子:打开图片并显示.打开图片利用Qt的标准文件对话框,第一步是利用OpenCV创建窗口并显示. 添加一个Button,转到信号槽添加代码: using namespace cv; Mat image ...

  4. mmwave

    毫米波(mmWave) 致力于支持5G应用创新开发,集成在BEEcube BEE7基带平台上的赛灵思256QAM毫米波调制解调器IP为宽带回程原型设计提供完整的开箱即用型解决方案 赛灵思公司 (NAS ...

  5. Adobe 官方公布的 RTMP 规范

    原文:  http://blog.csdn.net/defonds/article/details/17534903 RTMP 规范中文版 PDF 下载地址 译序:本文是为截至发稿时止最新 Adobe ...

  6. node安装与升级

    node安装与升级 1.安装 sudo apt-get install nodejs sudo apt-get install npm 2.升级 如果node不是最新的,node有一个模块叫n,是专门 ...

  7. oracle:程序后台提示Io异常: The Network Adapter could not establish the connection)

    今天要用tomcat部署一个系统,windows环境下,oracle和程序在一台机器上. 在配置jndi时,直接写成 jdbc:oracle:thin:@127.0.0.1:1521:orcl.启动程 ...

  8. 后台while收发过程

    fuse_loop_mt.c 中fuse_do_work函数使用while循环在后台不断运行,每一个while循环中,主要有两个操作. 1. fuse_session_receive_buf(mt-& ...

  9. BlueSea笔记<1>--Cricket初探

    最近在看Cricket这个实现了Actor模式的F#开源框架,对其工作方式作了一番探究.首先来看一段简单的例子代码: type Say = | Hello let greeter = actor { ...

  10. 百度地图API应用之获取用户的具体位置

    功能的大概:用户通过点击地图上面的位置,在地图上面进行描点,然后再把获取的到的地理位置保存到地图上面的地址栏目中. 主要是百度地图API的使用 .代码如下: var map = new BMap.Ma ...