把这几天写的东西上传一下
写博客的意义大概就是整理一下思路 以及方便日后复习
不得不说 把代码放在文件夹里
做完我是不会过目的
写博客 或许会增加我的成就感
从而 会多注意一下吧
哈哈 csdn现在也高大上了很多嘛
poj1741 Tree
题目大意:求(u,v)满足dis(u,v)<=k的点对数 N<=10000
点分治 LNWC2016新学到的 Orz
大概是 把所有的边分为经过点 x (重心) 和不经过点x
不经过点x的 多棵子树递归处理
可以证明递归次数不超过 logN 次
刚学完时候想尝试徒手写失败了= =
参考了hzwer的点分治= =
在这里%%%
但是我发现了个问题 点分治每次找的不是重心 但黄学长说没影响 不知道为什么
此题题解:
对于每次处理的根节点
求出它的子树所有点到距离 排序
ans+= dis(u,root)+dis(root,v)<=k 的点对数
但对于(u,v)在一棵子树上的情况 本不应该算入
所以答案还要减去(u,v)在一棵子树的情况
这个点分治是模仿hzwer实现的 有时间再写一发这题或别的题QAQ
在这里立个flag呦
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=10010;
const int inf=0x7fffffff;
struct E {int to,nxt,val;}edge[N*2];
int idx[N],can[N],size[N],deep[N],d[N],f[N];
int tot,root,ans,ret,sum,p;
int n,k;
void init(){
tot=1;root=0;ans=0;sum=n;
fill(idx,idx+N,0);
fill(can,can+N,1);
fill(size,size+N,0);
fill(deep,deep+N,0);
fill(d,d+N,0);
fill(f,f+N,0);f[0]=inf;
}
void addedge(int from,int to,int val){
edge[tot].to=to;edge[tot].val=val;edge[tot].nxt=idx[from];idx[from]=tot++;
}
void getroot(int x,int fa){
size[x]=1;f[x]=0;
for(int t=idx[x];t;t=edge[t].nxt){
E e=edge[t];
if(can[e.to] && e.to!=fa){
getroot(e.to,x);
f[x]=max(f[x],size[e.to]);
size[x]+=size[e.to];
}
}
f[x]=max(f[x],sum-size[x]);
if(f[x]<f[root]) root=x;
}
void getdeep(int x,int fa){
deep[++p]=d[x];
for(int t=idx[x];t;t=edge[t].nxt){
E e=edge[t];
if(can[e.to] && e.to!=fa) {
d[e.to]=d[x]+e.val;
getdeep(e.to,x);
}
}
}
int calc(int x,int now){
ret=0;d[x]=now;p=0;
getdeep(x,0);
sort(deep+1,deep+1+p);
int r=p;
for(int l=1;l<=p;l++){
while(deep[l]+deep[r]>k) r--;
if(r<=l) break;
ret+=(r-l);
}
return ret;
}
void work(int x){
ans+=calc(x,0);
can[x]=0;
for(int t=idx[x];t;t=edge[t].nxt){
E e=edge[t];
if(can[e.to]){
sum=size[e.to];
ans-=calc(e.to,e.val);
root=0;
getroot(e.to,0);
work(root);
}
}
}
int main(){
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
while(1){
scanf("%d%d",&n,&k);
if(n==0 && k==0) break;
init();
for(int i=1;i<n;i++){
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
addedge(x,y,w);addedge(y,x,w);
}
getroot(1,0);
work(root);
printf("%d\n",ans);
}
return 0;
}