一开始又看错题,以为同样路径上不同的休息站是算不同路径,后来发现休息站只是路径合法的条件
毫无疑问是树的分治,下面我们只要考虑计算能建休息站的路径
我们把阳看作路径权值为1,阴作为路径权值-1
点分治之后,休息站的建立只有三种情况,在根,在之前的子树路径上,在现在的子树路径上
我们先考虑休息站在根到子树的路径上,我们设d[x]表示点x到根的路径距离
能建也就是说在x到根的路径上存在一点y,d[y]=d[x],也就是当前距离之前是否出现过,打个标记即可
然后我们只要分别记录一下当前由根出发路径和为x,能否在这条路径上建休息站的路径数目就很容易统计了
注意一些地方的漏算和重复计算
1 type node=record 2 po,next,num:longint; 3 end; 4 5 var w,g:array[-100010..100010,0..1] of int64; 6 s,p,f,d:array[0..100010] of longint; 7 v:array[0..100010] of boolean; 8 can:array[-100010..100010] of longint; 9 e:array[0..200010] of node; 10 l,r,root,len,i,x,tot,y,z,n:longint; 11 ans:int64; 12 13 function max(a,b:longint):longint; 14 begin 15 if a>b then exit(a) else exit(b); 16 end; 17 18 procedure add(x,y,z:longint); 19 begin 20 inc(len); 21 e[len].po:=y; 22 e[len].num:=z; 23 e[len].next:=p[x]; 24 p[x]:=len; 25 end; 26 27 procedure getroot(x,fa:longint); 28 var i,y:longint; 29 begin 30 i:=p[x]; 31 s[x]:=1; 32 f[x]:=0; 33 while i<>0 do 34 begin 35 y:=e[i].po; 36 if not v[y] and (y<>fa) then 37 begin 38 getroot(y,x); 39 s[x]:=s[x]+s[y]; 40 f[x]:=max(f[x],s[y]); 41 end; 42 i:=e[i].next; 43 end; 44 f[x]:=max(f[x],tot-s[x]); 45 if f[x]<f[root] then root:=x; 46 end; 47 48 procedure dfs(x,fa:longint); 49 var i,y:longint; 50 begin 51 if can[d[x]]>0 then 52 begin 53 inc(g[d[x],1]); 54 ans:=ans+w[-d[x],1]+w[-d[x],0]; 55 end 56 else begin 57 inc(g[d[x],0]); 58 ans:=ans+w[-d[x],1]; 59 end; 60 inc(can[d[x]]); 61 r:=max(r,d[x]); 62 if l>d[x] then l:=d[x]; 63 i:=p[x]; 64 while i<>0 do 65 begin 66 y:=e[i].po; 67 if not v[y] and (y<>fa) then 68 begin 69 d[y]:=d[x]+e[i].num; 70 dfs(y,x); 71 end; 72 i:=e[i].next; 73 end; 74 dec(can[d[x]]); 75 end; 76 77 procedure work(x:longint); 78 var i,y,j:longint; 79 begin 80 v[x]:=true; 81 i:=p[x]; 82 l:=0; r:=0; 83 w[0,0]:=1; //注意根节点可以作为终点 84 while i<>0 do 85 begin 86 y:=e[i].po; 87 if not v[y] then 88 begin 89 d[y]:=e[i].num; 90 dfs(y,x); 91 ans:=ans+(w[0,0]-1)*g[0,0]; //注意当前子树内不能建休息站且路径和为0可以和之前的子树内(不包括单独根节点)这样的路径组成合法路径(根节点是休息站),而之前的计算我们是没有算进去的 92 for j:=l to r do 93 begin 94 w[j,0]:=w[j,0]+g[j,0]; //更新 95 w[j,1]:=w[j,1]+g[j,1]; 96 g[j,0]:=0; g[j,1]:=0; 97 end; 98 end; 99 i:=e[i].next; 100 end; 101 for j:=l to r do 102 begin 103 w[j,0]:=0; 104 w[j,1]:=0; 105 end; 106 i:=p[x]; 107 while i<>0 do 108 begin 109 y:=e[i].po; 110 if not v[y] then 111 begin 112 root:=0; 113 tot:=s[y]; 114 getroot(y,0); 115 work(root); 116 end; 117 i:=e[i].next; 118 end; 119 end; 120 121 begin 122 readln(n); 123 for i:=1 to n-1 do 124 begin 125 readln(x,y,z); 126 if z=0 then z:=-1; 127 add(x,y,z); 128 add(y,x,z); 129 end; 130 f[0]:=n+1; 131 tot:=n; 132 len:=0; 133 getroot(1,0); 134 work(root); 135 writeln(ans); 136 end.