题目大意:(同poj1741,刷一赠一系列)
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 40010 #define INF 0x3f3f3f3f using 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 树的分治(点分治)
原文地址:http://blog.csdn.net/jiangyuze831/article/details/39996941