(Same as poj1741, a series of TIPS)
Code:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 40010#define INF 0x3f3f3f3fusing namespace std;int points,edges,k;int head[MAX],total;int next[MAX << 1],length[MAX << 1],aim[MAX << 1];bool v[MAX];int cnt[MAX];int _size,size[MAX],root,_total;int dis[MAX],p;char s[10];inline void Add(int x,int y,int len);void Work(int x);void GetRoot(int x,int last);inline int Count(int x,int len);void GetDis(int x,int last,int len);int main(){cin >> points >> edges;for(int x,y,z,i = 1;i <= edges; ++i) {scanf("%d%d%d%s",&x,&y,&z,s);Add(x,y,z),Add(y,x,z);}cin >> k;Work(1);int ans = 0;for(int i = 1;i <= points; ++i)ans += cnt[i];cout << ans << endl;return 0;}inline void Add(int x,int y,int len){next[++total] = head[x];aim[total] = y;length[total] = len;head[x] = total;}void Work(int x){_total = size[x] ? size[x]:points;_size = INF;GetRoot(x,0);x = root;v[x] = true;cnt[x] = Count(x,0);for(int i = head[x];i;i = next[i]) {if(v[aim[i]])continue;cnt[x] -= Count(aim[i],length[i]);Work(aim[i]);}}void GetRoot(int x,int last){size[x] = 1;int max_size = 0;for(int i = head[x];i;i = next[i]) {if(v[aim[i]] || aim[i] == last)continue;GetRoot(aim[i],x);size[x] += size[aim[i]];max_size = max(max_size,size[aim[i]]);} max_size = max(max_size,_total - size[x]);if(_size > max_size)_size = max_size,root = x;}inline int Count(int x,int len){p = 0;GetDis(x,0,len);sort(dis + 1,dis + p + 1);int l = 1,r = p,re = 0;while(l < r) {if(dis[l] + dis[r] <= k)re += (r - l),++l;else--r;}return re;}void GetDis(int x,int last,int len){dis[++p] = len;for(int i = head[x];i;i = next[i]) {if(v[aim[i]] || aim[i] == last)continue;GetDis(aim[i],x,len + length[i]);}}
Poj 1987 bzoj 3365 distance statistics tree shard (point shard)