Title Description
Farmer John is on his way to planning his own farm. The structure of his farm was like a tree: the farm had n Barns (1<= n <=100,000), which were linked by N-1 Road. In this way, he could pass through the barn roads across the barns. Farmer John wants to choose a route: The starting and ending points of this route are two different barns in the farm, which cannot be repeated two times over an edge. Farmer John was worried that the path might be too long, so he wanted to find a break on the route (of course, the break could not be a starting point or an end point).
Each side is lined with cattle, either charcolais (white hair) or Angus (black). Farmer John was a wise man, so he wanted to balance the yin and yang on both sides of the path while he passed the path. He chooses a path that will allow him to go from the starting point to the rest station, and from the rest station to the end of the road, both sides of the Charcolais cattle and Angus herd the same total number of cattle.
Farmer John was curious as to how many of the balanced paths he could find above. We believe that the two paths are considered different if and only if the set of edges of the two alignments is not the same, otherwise they are considered to be the same route. Even if there are multiple effective "rest stations" on the route to balance the route, we only remember one route.
Please help calculate how many different balanced alignments are available.
Analysis
I read the wrong question from the beginning ... The key is to find a dividing point on a path, and then both sides of the road are two of the same number of cattle.
Well, let's analyze it, we can first think of different cows as the weights of 1 and 1. Then find a path, and a cut point, so that the ends of the balance. Let's set a root, and when the root is Rx, we emit a size_rx path from the root, which we call a sub-path. Now all we have to do is pair. This problem can be directly opened a bucket to do, two path weights added up equals 0, it is possible in the answer. So now the question is, how is the path legal?
Let's consider the sub-path first. As long as the weighted value of a point on the sub-path is the same as the endpoint, then this sub-path has a cut point.
We know that the path by two of the path together, as long as there is a cut point, this road is legal, indifferent two have cut points, not to mention. So we can count it. There are some special cases, this is not said.
Look at the complexity of the time. For a subtree, processing must pass through the complexity of his path is SIZE_RX, so it can be divided into a point of treatment. N log n solves the problem.
Code
#include <cstdio>#include <iostream>#include <algorithm>Using namespace Std;typedef long Long ll;constints=100005; constintn=500005; struct rec{intsig,cnt;//cntEqualPOS}buc[n * *][2],TR[N];intDis[n],first[n * *],Next[N * *],b[n * *],pd[n],c[n * *],st[n],en[n],i,x,y, t,n,t1,tt,ttt,t2,col,vis[n],f[n],cnt[n],up[n],go[n];ll ans;intCrint x,int y,intT) {ttt++; b[ttt]=y; C[ttt]= (t==1)?1:-1;Next[ttt]=first[x]; first[x]=TTT;}intDfsint x,int y) {tt++;TR[tt].cnt=dis[x];if(pd[dis[x]]!=0)TR[tt].sig=1;Else TR[tt].sig=0;if(pd[dis[x]]==0) pd[dis[x]]=x; for(intp=first[x];p; p=Next[P]) {if(b[p]!=y&&!VIS[B[P]]) {dis[b[p]]=dis[x]+C[P]; DFS (B[P),x); } }if(pd[dis[x]]==x) pd[dis[x]]=0;}intThrint x,int y) {cnt[x]=1; for(intp=first[x];p; p=Next[P]) {if(b[p]!=y&&!vis[b[p]] {thr (b[p]),x); cnt[x]+=CNT[B[P]]; } }}intFindint x,int y){intret=x, TMP; f[x]=up[x]; for(intp=first[x];p; p=Next[P])if(b[p]!=y&&!VIS[B[P]]) f[x]=max (cnt[b[p]],f[x]); for(intp=first[x];p; p=Next[P])if(b[p]!=y&&!VIS[B[P]]) {up[b[p]]=up[x]+cnt[x]-CNT[B[P]]; Tmp=find (B[p],x);if(f[ret]>f[tmp]) ret=tmp; }returnRET;} ll Getans () {ll ret=0; for(intI=1; i<=t2;i++) for(intj=st[i];j<=en[i];j++) {if(buc[TR[j].cnt+s][TR[J].sig].sig!=col) {buc[TR[j].cnt+s][TR[J].sig].sig=col; buc[TR[j].cnt+s][TR[j].sig].cnt=1; }Elsebuc[TR[j].cnt+s][TR[j].sig].cnt++; } for(intI=1; i<=t2;i++) { for(intj=st[i];j<=en[i];j++) buc[TR[j].cnt+s][TR[j].sig].cnt--; for(intj=st[i];j<=en[i];j++) {if(TR[j].cnt==0&&TR[j].sig==1) ret++;if(buc[-TR[j].cnt+s][1].sig==col) ret+=buc[-TR[j].cnt+s][1].cnt;if((TR[j].sig==1||TR[j].cnt==0) && (buc[-TR[j].cnt+s][0].sig==col)) ret+=buc[-TR[j].cnt+s][0].cnt; } }returnRET;}intSolveint x,int y){//printf("%d\ n",&x); vis[x]=1; tt=0; T2=0; for(intp=first[x];p; p=Next[P]) {if(vis[b[p]]==0) {//PD[0]=x; t2++; st[t2]=en[t2-1]+1; dis[b[p]]=dis[x]+C[P]; DFS (B[P),x); En[t2]=tt;//PD[0]=0; }} col++; Ans+=getans (); for(intp=first[x];p; p=Next[P]) {if(vis[b[p]]==0) {thr (b[p],x); t1++; up[b[p]]=0; Go[t1]=find (B[p],x); dis[go[t1]]=0; Solve (Go[t1],x); } }}intMain () {Freopen ("Angus.in","R", stdin); Freopen ("Angus.out","W", stdout); scanf"%d", &n); for(i=1; i<n;i++) {scanf (" %d%d%d",&x,&y, &t); Crx,y, t); Cry,x, t); } THR (1,0); t1++; Hot1]=find (1,0); dis[go[1]]=0; Solve (go[1],0);printf("%lld", ans);}
Reflection
This problem is the first to use GDB debugging the topic, is not very familiar, to practice more.
I read the program debugging ability is still not strong, may be lazy, need to correct, because once figured out, can save a lot of time.
It's not good to be distracted when you hit the code.
JZOJ3234 Yin and Yang