3697: 采药人的路径

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit:
681  Solved: 246
[Submit][Status][Discuss]

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

HINT

对于100%的数据,N ≤ 100,000。

Source

3127: [Usaco2013 Open]Yin and Yang

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 116  Solved: 82
[Submit][Status][Discuss]

Description

Farns (1 <= N <= 100,000) which are connected by N-1 edges such that
he can reach any barn from any other. Farmer John wants to choose a path which starts and ends at two
different barns, such that he does not traverse any edge twice. He worries that his path might be a
little long, so he also wants to choose another "rest stop" barn located on this path (which is distinct
from the start or the end). Along each edge is a herd of cows, either of the Charcolais (white hair)
or the Angus (black hair) variety. Being the wise man that he is, Farmer John wants to balance the
forces of yin and yang that weigh upon his walk. To do so, he wishes to choose a path such that he
will pass by an equal number of Charcolais herds and Angus herds-- oth on the way from the start to
his rest stop, and on theway from the rest stop to the end. Farmer John is curious how many different
paths he can choose that  are "balanced" as described above. Two paths are different only if they
consist of different setsof edges; a path should be counted only once even if there are multiple valid
"rest stop" locationsalong the path that make it balanced. Please help determine the number of
paths Farmer John can cho

Input

* Line 1: The integer N.
* Lines 2..N: Three integers a_i, b_i and t_i, representing the two barns
that edge i connects. t_i 
is 0 if the herd along that edge is Charcolais, and 1 if the herd is
Angus.

Output

Line 1: One integer, representing the number of possible paths Farmer John
can choose from.

Sample Input

7
1 2 0
3 1 1
2 4 0
5 2
0
6 3 1
5 7 1
INPUT DETAILS:
There are 7 barns and 6 edges. The
edges from 1 to 2, 2 to 4 and 2 to 5 have Charcolais herds along

them.

Sample Output

1
OUTPUT DETAILS:
No path of
length 2 can have a suitable rest stop on it, so we can only consider paths of
length 4.
The only path that has a suitable rest stop is 3-1-2-5-7, with a
rest stop at 2.

HINT

Source

Gold

Solution

这道题有点厉害

首先肯定想到点分治,问题在于如何统计答案

首先对于阴阳边,我们可以赋权值+1/-1,这样路径阴阳数目就比较直观了

定义$f[i][0/1]$表示当前子树中路径和为$i$的路径个数,0/1表示路径上是否存在前缀为$i$的点

定义$g[i][0/1]$表示之前前子树中路径和为$i$的路径个数,0/1同理

那么对答案的贡献就是$g[0][0]*f[0][0]+\sum (g[-i][0]]*f[i][1]+g[-i][1]*f[i][0]+g[-i][1]*f[i][1])$

要注意考虑下标为负的情况...全部+N即可

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 100010
#define LL long long
int N;
struct EdgeNode{int next,to,val;}edge[MAXN<<];
int head[MAXN],cnt=;
void AddEdge(int u,int v,int w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].val=w;}
void InsertEdge(int u,int v,int w) {AddEdge(u,v,w); AddEdge(v,u,w);}
int size[MAXN],maxx[MAXN],root,Sz; bool visit[MAXN];
void DFSRoot(int now,int last)
{
size[now]=; maxx[now]=;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=last && !visit[edge[i].to])
{
DFSRoot(edge[i].to,now);
size[now]+=size[edge[i].to];
maxx[now]=max(maxx[now],size[edge[i].to]);
}
maxx[now]=max(maxx[now],Sz-size[now]);
if (maxx[now]<maxx[root]) root=now;
}
int deep[MAXN],maxd,md,mark[MAXN<<],D[MAXN<<];
LL f[MAXN<<][],g[MAXN<<][],ans;
void DFS(int now,int last)
{
maxd=max(maxd,deep[now]);
if (mark[D[now]]) f[D[now]][]++; else f[D[now]][]++;
mark[D[now]]++;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=last && !visit[edge[i].to])
{
deep[edge[i].to]=deep[now]+;
D[edge[i].to]=D[now]+edge[i].val;
DFS(edge[i].to,now);
}
mark[D[now]]--;
}
void Get(int x,int val)
{
D[x]=N+val; deep[x]=;
maxd=; DFS(x,); md=max(maxd,md);
ans+=(g[N][]-)*f[N][];
for (int i=-maxd; i<=maxd; i++)
ans+=g[N-i][]*f[N+i][]+g[N-i][]*f[N+i][]+g[N-i][]*f[N+i][];
for (int i=N-maxd; i<=N+maxd; i++)
g[i][]+=f[i][],g[i][]+=f[i][],f[i][]=f[i][]=;
}
void Divide(int x)
{
visit[x]=;
g[N][]=; md=;
for (int i=head[x]; i; i=edge[i].next)
if (!visit[edge[i].to]) Get(edge[i].to,edge[i].val);
for (int i=-md; i<=md; i++) g[N+i][]=g[N+i][]=;
for (int i=head[x]; i; i=edge[i].next)
if (!visit[edge[i].to])
{
Sz=size[edge[i].to]; root=;
DFSRoot(edge[i].to,x);
Divide(root);
}
}
int main()
{
N=read();
for (int x,y,z,i=; i<=N-; i++)
x=read(),y=read(),z=read(),InsertEdge(x,y,z? z:-);
Sz=maxx[root=]=N;
DFSRoot(,);
Divide(root);
printf("%lld\n",ans);
return ;
}

【BZOJ-3697&3127】采药人的路径&YinandYang 点分治 + 乱搞的更多相关文章

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

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

  2. 【BZOJ 3697】采药人的路径

    题目链接: TP 题解: 调了好久233. 大概想一想就是树分,然后考虑这样路径(u,v)的特征,以根节点(root)切开,u到root的阴阳差值,和v到root巧合互为相反数,然后考虑要有一个点可作 ...

  3. BZOJ_3697_采药人的路径_点分治

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

  4. 【BZOJ】【3697】采药人的路径&【3127】【USACO2013 Open】Yin and Yang

    点分治 Orz hzwer 倒是比较好想到点分治……然而在方案统计这里,我犯了两个错误…… 1.我比较傻逼的想的是:通过儿子来更新父亲,也就是统计以x为根的子树中xxxx的路径有多少条……这样转移. ...

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

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

  6. bzoj 3697: 采药人的路径【点分治】

    点分治,设当前处理的块的重心为rt,预处理出每个子树中f[v][0/1]表示组合出.没组合出一对值v的链数(从当前儿子出发的链),能组合出一对v值就是可以有一个休息点 然后对于rt,经过rt且合法的路 ...

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

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

  8. 【BZOJ3697】采药人的路径(点分治)

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

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

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

随机推荐

  1. Symbol ES6 新增的一种值类型数据,表示一种绝不重复的值

    let s1 = Symbol(33); let s2 = Symbol(33); alert(typeof(s1)); //数据类型判断 // alert(s1.toString()); //可把一 ...

  2. 苹果IOS开发者账号的区别,企业账号,个人账号,公司团队账号,教育账号

    苹果IOS开发者账号总结 详细地址:https://developer.apple.com/programs/which-program/ 个人账号(Individual): 费用99美金一年, 该账 ...

  3. eap

    本文介绍了eap  

  4. ZooKeeper 笔记(4) 实战应用之【消除单点故障】

    关键节点的单点故障(Single Point of Failure)在大型的架构中,往往是致命的.比如:SOA架构中,服务注册中心(Server Register)统一调度所有服务,如果这个节点挂了, ...

  5. Theano2.1.11-基础知识之稀疏

    来自:http://deeplearning.net/software/theano/tutorial/sparse.html sparse 通常来说,稀疏矩阵可以和常规矩阵一样提供相同的功能.两者不 ...

  6. Expression Blend4经验分享:自适应布局浅析

    今天分享一下Blend制作自适应分辨率布局的经验,大家先看下效果图: 这是一个标准的三分天下的布局,两侧的红色区域是背景区域,是用来干吗的呢,下面简单的分析一下,大家就明白了. 1.拿到一个项目,进行 ...

  7. DOM 元素节点几何量与滚动几何量

    当在 Web 浏览器中查看 HTML 文档时,DOM 节点被解析,并被渲染成盒模型(如下图),有时我们需要知道一些信息,比如盒模型的大小,盒模型在浏览器中的位置等等,本文我们就来详细了解下元素节点的几 ...

  8. C#操作XML方法集合

    一 前言 先来了解下操作XML所涉及到的几个类及之间的关系  如果大家发现少写了一些常用的方法,麻烦在评论中指出,我一定会补上的!谢谢大家 * 1 XMLElement 主要是针对节点的一些属性进行操 ...

  9. md5加密篇(一)

    /// <summary> /// 获取文件的md5摘要 /// </summary> /// <param name="sFile">文件流& ...

  10. Android帧动画

    通过播放一张一张图片来实现一段动画 首先配置anim.xml: <?xml version="1.0" encoding="utf-8"?> < ...