jzoj3234. Yin Yang

Title description

Description
Farmer John is planning a stroll on his farm. The structure of his farm is like a tree: the farm has N barns (1<= N <=100,000), each linked by N-1 roads. In this way, he can pass through the roads between these barns to reach all the barns. Farmer John wants to choose a route: The start and end of this route are two different barns on the farm. This route cannot pass through an edge twice. Farmer John was worried that this path might be too long, so he wanted to find a rest point on the route (of course, this rest point cannot be the starting point or the end point).

On both sides of each side are cows, either Charcolais (white hair) or Angus (black hair). Farmer John is a smart man, so he wants to balance the power of yin and yang on both sides of the path as he passes through the path. He has to choose a path so that he has the same number of Charcolais and Angus herds on both sides of the road from the starting point to the rest stop, and from the rest stop to the end.

Farmer John wondered how many balanced paths he could find as mentioned above. We believe that if and only if the sets of sides of the two routes are different, the two routes are considered to be different, otherwise they are considered to be the same route. Even if there are multiple effective "rest stops" on the route to balance the route, we will only record it as one route.

Please help to calculate how many different balance routes there are.

Input
line 1: Contains an integer N.

Line 2... N: Each line contains three integers a_i, b_i and t_i, representing the two barns a_i and b_i connected by the i-th path. t_i represents the type of cattle on the i-th roadside: 0 represents Charcolais, and 1 represents Angus.

The output
output is only one line and contains an integer, which indicates the number of possible paths.

Sample Input
7

1 2 0

3 1 1

2 4 0

5 2 0

6 3 1

5 7 1

Sample Output
1

Data Constraint
1<= N <=100,000

Hint
does not have a route of length 2, so we can only consider a route of length 4. The route 3-1-2-5-7 rest point at 2 is a balanced route.

answer

Point Divide and Conquer Naked Questions (Relative)
Set white to -1 and black to 1, then find a path so that there is a certain point, so that the sum of the paths divided into two segments is 0.
Divide and conquer each point first. Ordinary point , if there is a prefix sum of 0 on the path from an ordinary point to a divide-and-conquer point , it is called a key point (also an ordinary point), which
may be different from the problem solution because I did not look at the problem solution
by maintaining each point to the point The weight and situation of the path on the governance point can determine whether a point is a key point (if the current sum appears in a previous position, then the sum of the path in the middle is 0). There is
initially a point with a sum of 0 (starting point) )
For a legal path (u-divide and conquer point-v), at least one of u and v is the key point, and sum[u]+sum[v]=0, plus u/v-divide and conquer point Legal situation (if and only if the sum of the point is 0, and there are at least 2 points before the sum is 0 )
Note that the subtraction of u and v are both key points

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define inf 2133333333
using namespace std;

int a[200001][3];
int ls[100001];
int size[100001];
int bz[100001];
int b[200001]; //special
int B[200001]; //normal
int c[200001];
int b2[100001];
int B2[100001];
int n,i,j,k,l,len,min1,min2,l1,l2;
long long ans;

void New(int x,int y,int z)
{
    
    
	++len;
	a[len][0]=y;
	a[len][1]=ls[x];
	ls[x]=len;
	a[len][2]=z;
}

void dfs2(int Fa,int t)
{
    
    
	int i;
	
	size[t]=1;
	
	for (i=ls[t]; i; i=a[i][1])
	if (a[i][0]!=Fa && !bz[a[i][0]])
	{
    
    
		dfs2(t,a[i][0]);
		size[t]+=size[a[i][0]];
	}
}

void dfs3(int Fa,int t,int Size)
{
    
    
	int i,sum=0,mx=Size;
	
	for (i=ls[t]; i; i=a[i][1])
	if (a[i][0]!=Fa && !bz[a[i][0]])
	{
    
    
		sum+=size[a[i][0]];
		mx=max(mx,size[a[i][0]]);
	}
	
	if (mx<min1)
	{
    
    
		min1=mx;
		min2=t;
	}
	
	for (i=ls[t]; i; i=a[i][1])
	if (a[i][0]!=Fa && !bz[a[i][0]])
	dfs3(t,a[i][0],Size+sum-size[a[i][0]]+1);
}

void dfs4(int Fa,int t,int s)
{
    
    
	int i;
	
	ans+=b[-s+100000];
	if (c[s+100000])
	{
    
    
		ans+=B[-s+100000]-b[-s+100000];
		
		if (!s && c[s+100000]>1)
		++ans;
	}
	
//	---
	
	++c[s+100000];
	
	for (i=ls[t]; i; i=a[i][1])
	if (a[i][0]!=Fa && !bz[a[i][0]])
	dfs4(t,a[i][0],s+a[i][2]);
	
	--c[s+100000];
}

void dfs5(int Fa,int t,int s)
{
    
    
	int i;
	
	++B[s+100000];
	if (B[s+100000]==1)
	B2[++l2]=s+100000;
	
	if (c[s+100000])
	{
    
    
		++b[s+100000];
		
		if (b[s+100000]==1)
		b2[++l1]=s+100000;
	}
	
//	---
	
	++c[s+100000];
	
	for (i=ls[t]; i; i=a[i][1])
	if (a[i][0]!=Fa && !bz[a[i][0]])
	dfs5(t,a[i][0],s+a[i][2]);
	
	--c[s+100000];
}

void dfs1(int t)
{
    
    
	int i;
	
	dfs2(0,t);
	min1=inf;
	dfs3(0,t,0);
	
	t=min2;
	bz[t]=1;
	
	l1=0;
	l2=0;
	
	for (i=ls[t]; i; i=a[i][1])
	if (!bz[a[i][0]])
	{
    
    
		++c[0+100000];
		
		dfs4(t,a[i][0],a[i][2]);
		dfs5(t,a[i][0],a[i][2]);
		
		--c[0+100000];
	}
	
	fo(i,1,l1) b[b2[i]]=0;
	fo(i,1,l2) B[B2[i]]=0;
	
	for (i=ls[t]; i; i=a[i][1])
	if (!bz[a[i][0]])
	dfs1(a[i][0]);
}

int main()
{
    
    
	scanf("%d",&n);
	fo(i,2,n)
	{
    
    
		scanf("%d%d%d",&j,&k,&l);
		l=l*2-1;
		
		New(j,k,l);
		New(k,j,l);
	}
	
	dfs1(1);
	
	printf("%lld\n",ans);
}

Guess you like

Origin blog.csdn.net/gmh77/article/details/100003237