[bzoj 1468][poj 1741]Tree [点分治]
Description
Give a tree with n vertices,each edge has a length(positive integer less than 1001).
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.
Input
The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
The last test case is followed by two zeros.
The last test case is followed by two zeros.
Output
For each test case output the answer on a single line.
Sample Input
5 4 1 2 3 1 3 1 1 4 2 3 5 1 0 0
Sample Output
8
又一道点分治膜版题
我果然是只会做膜版啊
还是贴上vector造图的代码吧
虽然它RE了
用数组膜你邻接表AC
我也很迷啊
好好好一个小时后的我发现自己一个小时前太sb了
居然忘了复原vector G了
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 inline int read(){ 9 char ch; 10 int re=0; 11 bool flag=0; 12 while((ch=getchar())!='-'&&(ch<'0'||ch>'9')); 13 ch=='-'?flag=1:re=ch-'0'; 14 while((ch=getchar())>='0'&&ch<='9') re=re*10+ch-'0'; 15 return flag?-re:re; 16 } 17 18 struct edge{ 19 int to,w; 20 edge(int to=0,int w=0): 21 to(to),w(w){} 22 }; 23 const int maxn=10005; 24 vector<edge> G[maxn]; 25 int son[maxn],F[maxn]; 26 int d[maxn],deep[maxn]; 27 bool vis[maxn]; 28 int sum,ans,root; 29 int n,K; 30 31 inline void add_edge(int from,int to,int w){ 32 G[from].push_back(edge(to,w)); 33 G[to].push_back(edge(from,w)); 34 } 35 36 bool init(){ 37 n=read(); 38 if(!n) return 0; 39 memset(G,0,sizeof G); 40 memset(vis,0,sizeof vis); 41 K=read(); 42 for(int i=0;i<n-1;i++){ 43 int from=read(),to=read(),w=read(); 44 add_edge(from,to,w); 45 } 46 return 1; 47 } 48 49 void getroot(int x,int fa){ 50 son[x]=1; 51 F[x]=0; 52 int dd=G[x].size(); 53 for(int i=0;i<dd;i++){ 54 edge &e=G[x][i]; 55 if(e.to!=fa&&!vis[e.to]){ 56 getroot(e.to,x); 57 son[x]+=son[e.to]; 58 F[x]=max(F[x],son[e.to]); 59 } 60 } 61 F[x]=max(F[x],sum-son[x]); 62 if(F[x]<F[root]) root=x; 63 } 64 65 void getdeep(int x,int fa){ 66 deep[++deep[0]]=d[x]; 67 int dd=G[x].size(); 68 for(int i=0;i<dd;i++){ 69 edge &e=G[x][i]; 70 if(e.to!=fa&&!vis[e.to]){ 71 d[e.to]=d[x]+e.w; 72 getdeep(e.to,x); 73 } 74 } 75 } 76 77 int calc(int x,int now){ 78 d[x]=now; 79 deep[0]=0; 80 getdeep(x,0); 81 sort(deep+1,deep+deep[0]+1); 82 int t=0; 83 for(int l=1,r=deep[0];l<r;){ 84 if(deep[l]+deep[r]<=K){ 85 t+=r-l; 86 l++; 87 } 88 else r--; 89 } 90 return t; 91 } 92 93 void work(int x){ 94 ans+=calc(x,0); 95 vis[x]=1; 96 int dd=G[x].size(); 97 for(int i=0;i<dd;i++){ 98 edge &e=G[x][i]; 99 if(!vis[e.to]){ 100 ans-=calc(e.to,e.w); 101 sum=son[e.to]; 102 root=0; 103 getroot(e.to,root); 104 work(root); 105 } 106 } 107 } 108 109 void solve(){ 110 sum=F[root=0]=n; 111 ans=0; 112 getroot(1,0); 113 work(root); 114 printf("%d\n",ans); 115 } 116 117 int main(){ 118 //freopen("temp.in","r",stdin); 119 while(init()) 120 solve(); 121 return 0; 122 }
他说你任何为人称道的美丽 不及他第一次遇见你