对于一棵树,fdrt找到重心,然后分治每个子树。

在一棵以重心为根的树上,符合条件的链是:

  1.过重心(根)

  2.不过重心

对于1我们只需dfs出距离重心(根)的距离然后统计再减去有重叠的边

对于2我们只需递归处理子树,这样2就分为过子树的根(重心)的链和不过子树根(重心)的链······

这就是点分治啦,貌似边分治更优,但是为了减少代码量,效率什么的我统统都不要(╬▔皿▔)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define read(x) x=getint()
using namespace std;
const int N=20003;
inline const int max( const int &a, const int &b) {return a>b?a:b;}
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
struct node {
int nxt, to, w;
} E[N<<1];
int point[N], size[N], ma[N], n, cnt=0, rt=0, ans=0, table[N], tn, di[N];
bool vis[N];
inline void insect( int x, int y, int z) {
cnt++;
E[cnt].nxt = point[x];
E[cnt].to = y;
E[cnt].w = z;
point[x] = cnt;
}
inline void fdrt( int x, int fa, int s) {
size[x] = 1;
ma[x] = 0;
for( int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if ( !vis[E[tmp].to] && E[tmp].to != fa) {
fdrt( E[tmp].to, x, s);
size[x] += size[E[tmp].to];
ma[x] = max( ma[x], size[E[tmp].to]);
}
if ( s - ma[x] > ma[x])
ma[x] = s - ma[x];
if ( ma[x] < ma[rt])
rt = x;
}
inline void mktb( int x, int fa) {
table[ ++tn] = di[x];
for( int tmp = point[x]; tmp; tmp = E[tmp].nxt)
if ( !vis[E[tmp].to] && E[tmp].to != fa) {
di[E[tmp].to] = di[x] + E[tmp].w;
mktb( E[tmp].to, x);
}
}
inline int work( int x, int beg) {
int cn0 = 0, cn1 = 0, cn2 = 0;
tn = 0;
di[x] = beg;
mktb( x, -1);
for( int i = 1; i <= tn; ++i) {
switch ( table[i] % 3) {
case 0:
++cn0;
break;
case 1:
++cn1;
break;
case 2:
++cn2;
break;
}
}
return cn0 * cn0 + ( ( cn1 * cn2) << 1);
}
inline void dfs( int x, int s) {
vis[x] = 1;
ans += work( x, 0);
for( int tmp = point[x], ss; tmp; tmp = E[tmp].nxt)
if ( !vis[E[tmp].to]) {
ans -= work( E[tmp].to, E[tmp].w);
if ( size[E[tmp].to] > size[x])
ss = s - size[x];
else
ss = size[E[tmp].to];
rt = 0;
fdrt( E[tmp].to, x, ss);
dfs( rt, ss);
}
}
inline int gcd( int x, int y) {
int r = x % y;
while ( r) {
x = y;
y = r;
r = x % y;
}
return y;
}
int main() {
read( n);
int u, v, e;
for( int i = 1; i < n; ++i) {
read( u);
read( v);
read( e);
e %= 3;
insect( u, v, e);
insect( v, u, e);
}
ma[0] = n+3;
memset( vis, 0, sizeof(vis));
fdrt( (n+1)>>1, -1, n);
dfs( rt, n);
int m = n * n, tong = gcd( ans, m);
printf( "%d/%d\n", ans / tong, m / tong);
return 0;
}

点分治完成啦,找重心估计s时偷了点懒效率立刻就低了∑(っ °Д °;)っ还是改回来了

还有我的码风这次有点奇怪⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄.是不是不再像以前那么挤了ヾ (o ° ω ° O ) ノ゙

【BZOJ 2152】聪聪可可 点分治的更多相关文章

  1. 洛谷 P2634 BZOJ 2152 【模板】点分治(聪聪可可)

    题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...

  2. 【BZOJ 2152】 聪聪可可

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2152 [算法] 点分治 [代码] #include<bits/stdc++.h ...

  3. [bzoj2152][聪聪和可可] (点分治+概率)

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  4. BZOJ 2152:聪聪可可(树上点分治)

    题目链接 题意 中文题意. 思路 和上一题类似,只不过cal()函数需要发生变化. 题目中要求是3的倍数,那么可以想到 (a + b) % 3 == 0 和 (a % 3 + b % 3) % 3 = ...

  5. 「BZOJ 2152」聪聪可可

    题目链接 戳这 \(Solution\) 这道题看起来就像点分治对吧.没错就是点分治. 什么是点分治 如果你不会点分治,可以去看看这儿 现在看到这里,首先确保你已经会了点分治,如果不会你还往下看,听不 ...

  6. BZOJ 2152: 聪聪可可 树分治

    2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...

  7. 【BZOJ】2152: 聪聪可可(点分治)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2152 随便点分..... 只是我在考虑一个地方逗乐.. 当路径长度mod3=0的点数直接乘起来就好. ...

  8. BZOJ 2152: 聪聪可可 点分治

    2152: 聪聪可可 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php ...

  9. bzoj 2152: 聪聪可可 树的点分治

    2152: 聪聪可可 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 485  Solved: 251[Submit][Status] Descripti ...

随机推荐

  1. Oracle round函数是什么意思?怎么运用?

    如何使用 Oracle Round 函数 (四舍五入) 描述 : 传回一个数值,该数值是按照指定的小数位元数进行四舍五入运算的结果. SELECT ROUND( number, [ decimal_p ...

  2. NSIS来自己设定快捷方式的图标

    CreateShortCut 快捷文件.lnk 目标文件 参数 图标文件 图标索引号 启动选项 键盘快捷键 描述 CreateShortCut "$DESKTOP\快捷方式.lnk" ...

  3. Netty 自动重连

    from: http://www.dozer.cc/2015/05/netty-auto-reconnect.html 自动重连 用 Netty 写 Client 和 Server 的时候必须要去处理 ...

  4. web一周

      学习web有一周了,老师进度有点小快,但是我还是感觉挺不错的.   对于一开始什么都不认识到能看懂是什么意思,并且可以写一些内容,我感觉还是比较欣慰,老师还是比较负责的,我每次都去找更远的代码学习 ...

  5. flex布局模式简单概述

    CSS3中新增一种弹性布局模型:flexbox.网上关于flex的介绍很多,这里介绍下常用的几个属性.弹性布局的特点是非常灵活.可根据剩余的宽高,灵活布局. 先用图片说明flex具有哪些属性.(网上盗 ...

  6. left join 条件区别

    t1: num | name-----+------ 1      | a 2      | b 3      | c t2: num | value-----+------- 1  | xxx 3 ...

  7. struts2 访问Web元素的4种方法

    完整代码 :Struts12AccessWebElement.rar 第一种也是最常用的一种方法实现这几个接口 RequestAware,SessionAware,ApplicationAware s ...

  8. [转]Android Studio创建Xposed模块项目时BridgeApi的正确添加方式

    使用Android Studio创建的空项目作为Xposed Module App,对于Api Jar包的引用方式,一开始是按照傻瓜式Jar Lib的处理方式,复制XposedBridgeApi-54 ...

  9. Xamarin.Android 反复报 Please Download android_m2repository_rxx.zip 的解决办法

    我原来一直用的是老版本的 Xamarin , android_m2repository_rxx.zip 早已在 C:\Users\XXX\AppData\Local\Xamarin\Android.S ...

  10. Java:注解(元数据)

    初识Java注解 所谓的元数据是指用来描述数据的数据,可能刚听到元数据的时候你会有点陌生,其实任何一个使用过struts或者hibernate的开发人员都在不知不觉中使用元数据,更通俗一点来说元数据是 ...