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. Html5 Egret游戏开发 成语大挑战(四)选关界面

    通过前面的开始界面基本上了解了eui的使用方法,可以简单快速的制作一个UI界面,本篇使用第二界面选关界面展示更为难一点的代码控制,来展现关卡地图的内容,请确保素材和资源完整,可以在前面的教程中找到下载 ...

  2. 嵌入支付宝SDK,出现“LaunchServices: ERROR: There is no registered handler for URL scheme alipay”错误

    应用项目中嵌入支付宝SDK,在模拟器运行app后,会出现“LaunchServices: ERROR: There is no registered handler for URL scheme al ...

  3. Centos 7 安装jdk 配置环境变量

    在Centos7 终端中,我们输入java -version可以看到java的版本,但是输入javac却没有反应 原因是系统中预装的是openjdk jre不是真正的jdk,所以还得自己装好,然后配置 ...

  4. JDK动态代理和CGLib动态代理简单演示

    JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期间创建接口的代理实例. 一.首先我们进行JDK动态代理的演示. 现在我们有一个简单的业务接口Saying,如下: package te ...

  5. Qt学习笔记 TableWidget使用说明和增删改操作的实现

    看一下效果很简单的一个小功能 先说分部讲一下过程 再给出详细代码 添加数据 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ...

  6. LINQ的高级应用

    ---恢复内容开始--- 本文不想罗列linq的通俗使用方法.因为很多博文都已经写得很详细了. 此处直接贴出源码,如果有需要的朋友可以参考,希望更多的朋友能够补充更多的linq的高级应用. 源码如下: ...

  7. SQL基础之XML

    1.XML数据类型 在SQL Server中xml数据类型可以用来保存xml文档,这个文档即可以是完整的xml文档和xml片段,这样开发者就可以像使用int数据类型一样来使用xml数据类型.不过xml ...

  8. ASP.NET 系列:单元测试之SmtpClient

    使用SmtpClient发送Email时,我们可以创建ISmtpClient接口和SmtpClientWrapper适配类,在单元测试中对ISmtpClient进行Mock或自定义FackeSmtpC ...

  9. 转一篇关于如何在Unity里使用Protobuf

    原帖地址: http://purdyjotut.blogspot.com/2013/10/using-protobuf-in-unity3d.html 先转过来,等时间合适了,再来收拾 Using P ...

  10. j-link或者swd调试

    两种 一.JTAG调试(5针), 二.SWD调试(2针), 在JTAG/SWD模式设置库函数 (在文件stm32f10x_gpio.c中): void GPIO_PinRemapConfig(uint ...