Description

采药人的药田是一个树状结构,每条路径上都种植着同种药材。
采药人以自己对药材独到的见解,对每种药材进行了分类。大致分为两类,一种是阴性的,一种是阳性的。
采药人每天都要进行采药活动。他选择的路径是很有讲究的,他认为阴阳平衡是很重要的,所以他走的一定是两种药材数目相等的路径。采药工作是很辛苦的,所以他希望他选出的路径中有一个可以作为休息站的节点(不包括起点和终点),满足起点到休息站和休息站到终点的路径也是阴阳平衡的。他想知道他一共可以选择多少种不同的路径。

Input

第1行包含一个整数N。
接下来N-1行,每行包含三个整数a_i、b_i和t_i,表示这条路上药材的类型。

Output

输出符合采药人要求的路径数目。

Sample Input

7
1 2 0
3 1 1
2 4 0
5 2 0
6 3 1
5 7 1

Sample Output

1

解题思路:

点分治要求在寻找到一条链时统计答案与重心在链的哪个位置无关。而显然这道题如果枚举重心为中转站是错误的,因为一条链只被统计一次,而中心位置很可能是错误的,所以我们需要修正这一点,就是统计重心路径上可能出现的中心位置。

换句话说,开四个桶来记录,分别记录当前子树内可能出现的中转站(出现过的距离重复,在差分的意义下说明出现和为0的区间),另外一个就是之前子树的答案,每次更新完合并桶就好了。

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
const int N=;
struct pnt{
int hd;
int dis;
int wgt;
bool vis;
}p[N];
struct ent{
int twd;
int lst;
int vls;
}e[N<<];
lnt f[N<<][],g[N<<][];
int has[N<<];
int n;
lnt top;
int cnt;
lnt ans;
int lim;
int size;
int root;
int maxsize;
void ade(int f,int t,int v)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
e[cnt].vls=v;
p[f].hd=cnt;
return ;
}
void grc_dfs(int x,int f)
{
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f||p[to].vis)
continue;
grc_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(p[to].wgt>maxs)
maxs=p[to].wgt;
}
if(maxs<size-p[x].wgt)
maxs=size-p[x].wgt;
if(maxs<maxsize)
{
maxsize=maxs;
root=x;
}
return ;
}
void ans_dfs(int x,int fa,int dep)
{
lim=std::max(lim,dep);
if(has[p[x].dis])
f[p[x].dis][]++;
else
f[p[x].dis][]++;
has[p[x].dis]++;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==fa||p[to].vis)
continue;
p[to].dis=p[x].dis+e[i].vls;
ans_dfs(to,x,dep+);
}
has[p[x].dis]--;
return ;
}
void bin_dfs(int x)
{
int maxd=;
p[x].vis=true;
g[n][]=;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].vis)
continue;
p[to].dis=n+e[i].vls;
lim=;
ans_dfs(to,to,);
maxd=std::max(maxd,lim);
ans+=f[n][]*(g[n][]-);
for(int j=-lim;j<=lim;j++)
ans+=g[n-j][]*f[n+j][]+g[n-j][]*f[n+j][]+g[n-j][]*f[n+j][];
for(int j=n-lim;j<=n+lim;j++)
{
g[j][]+=f[j][];
g[j][]+=f[j][];
f[j][]=f[j][]=;
}
}
for(int i=n-maxd;i<=n+maxd;i++)
g[i][]=g[i][]=;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].vis)
continue;
root=;
size=p[to].wgt;
maxsize=0x3f3f3f3f;
grc_dfs(to,to);
bin_dfs(root);
}
return ;
}
int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
c=c*-;
ade(a,b,c);
ade(b,a,c);
}
root=;
size=n;
maxsize=0x3f3f3f3f;
grc_dfs(,);
bin_dfs(root);
printf("%lld\n",ans);
return ;
}

BZOJ3697: 采药人的路径(点分治)的更多相关文章

  1. BZOJ3697采药人的路径——点分治

    题目描述 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的.采药人每天都要进行采药活动.他选择的路径 ...

  2. BZOJ3697:采药人的路径(点分治)

    Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的. 采药人每天都要进行采药 ...

  3. [bzoj3697]采药人的路径——点分治

    Brief Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的. 采药人每天 ...

  4. 【BZOJ3697】采药人的路径 点分治

    [BZOJ3697]采药人的路径 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是 ...

  5. [bzoj3697]采药人的路径_点分治

    采药人的路径 bzoj-3697 题目大意:给你一个n个节点的树,每条边分为阴性和阳性,求满足条件的链的个数,使得这条链上阴性的边的条数等于阳性的边的条数,且这条链上存在一个节点,这个节点到一个端点的 ...

  6. bzoj千题计划248:bzoj3697: 采药人的路径

    http://www.lydsy.com/JudgeOnline/problem.php?id=3697 点分治 路径0改为路径-1 g[i][0/1] 和 f[i][0/1]分别表示当前子树 和 已 ...

  7. BZOJ3697 采药人的路径 【点分治】

    题目 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的. 采药人每天都要进行采药活动.他选择的路径 ...

  8. 2019.01.09 bzoj3697: 采药人的路径(点分治)

    传送门 点分治好题. 题意:给出一棵树,边分两种,求满足由两条两种边数相等的路径拼成的路径数. 思路: 考虑将边的种类转化成边权−1-1−1和111,这样就只用考虑由两条权值为000的路径拼成的路径数 ...

  9. BZOJ 3697/3127 采药人的路径 (点分治)

    题目大意: 从前有一棵无向树,树上边权均为$0$或$1$,有一个采药人,他认为如果一条路径上边权为$0$和$1$的边数量相等,那么这条路径阴阳平衡.他想寻找一条合法的采药路径,保证阴阳平衡.然后他发现 ...

随机推荐

  1. 基于ArcGIS Flex API实现动态标绘(1.2)

    动态标绘API 1.2,相较前一版本号(点击进入),该版本号新增对基本标绘符号的支持,包含: 单点.多点.折线.手绘线.多边形.手绘多边形.矩形,并提供对应的编辑功能. 例如以下图所看到的,对多点的编 ...

  2. UITableView去掉最后切割线的一种方法

    UITableView以style:UITableViewStylePlain方式创建时.仅仅要有cell,就会有一条黑线 哪怕至于一个cell也会有,如图 在网上找了集中方法,都不好使,比方http ...

  3. 轻松python专题--文本

    基础篇:(取材于零基础学python) 7.1 python中的字符串简单介绍与经常使用函数 7.2 字符串常量 7.3 字符串的一般使用 7.4 改动字符串实例 7.5 文本解析 7.6 字符串格式 ...

  4. how to backup and restore database of SQL Server

    Back up 1,右键选中需要备份的数据库,Tasks-->Backup 2.General中,Destination,先remove掉之前的,然后再Add 需要注意的是,add的文件,必须要 ...

  5. 写了个关于tomcat项目部署脚本 shell

    #!/bin/bash tomcat_project_path=" /server/tomcat" tomcat_cp_path="/root/tools/apache- ...

  6. GOLANG 加密,解密,GUID 小方法

    golang的 MD5加密.BASE64解密  guid 的代码: /** * 用于加密,解密,(包含MD5加密和base64加密/解密)以及GUID的生成 * 时间: * zhifieya */ p ...

  7. BZOJ 2730 矿场搭建 Tarjan求割点

    思路: Tarjan求出来点双&割点 判一判就行了 //By SiriusRen #include <stack> #include <cstdio> #include ...

  8. Day2代码

    #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #defi ...

  9. jq 监听键盘事件

    其实这个也是挺简单的一些东西.也就是几个参数: 一.首先需要知道的是:         1.keydown()                 keydown事件会在键盘按下时触发. 2.keyup( ...

  10. 几种类型的db,以及最新的db排名,看一下

    5月数据库排名: http://geek.csdn.net/news/detail/196118 另外这篇文章里面提到了一些内嵌式数据库: http://blog.csdn.net/leagoal/a ...