【BZOJ1468】Tree
2016-01-18 21:45
344 查看
Description
给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于KInput
N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是kOutput
一行,有多少对点之间的距离小于等于kSample Input
71 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10
Sample Output
5又是一道点分治的题,方法同聪聪可可。
#include<cstdio> #include<algorithm> using namespace std; const int N=40010; int deep ,head ,son ,f ,d ,root,ans,n,sum,cnt,k; bool vis ; struct ee{int to,next,w;}e[N*2]; void insert(int u,int v,int w){ e[++cnt].to=v;e[cnt].next=head[u];e[cnt].w=w;head[u]=cnt; } void getroot(int x,int fa){ son[x]=1;f[x]=0; for (int i=head[x];i;i=e[i].next){ int v=e[i].to; if (vis[v]||v==fa) continue; getroot(v,x); son[x]+=son[v]; f[x]=max(f[x],son[v]); } f[x]=max(f[x],sum-f[x]); if (f[x]<f[root]) root=x; } void getdeep(int x,int fa){ deep[++deep[0]]=d[x]; for (int i=head[x];i;i=e[i].next){ int v=e[i].to; if (vis[v]||v==fa) continue; d[v]=d[x]+e[i].w; getdeep(v,x); } } int cal(int x,int now){ int t=0; d[x]=now;deep[0]=0; getdeep(x,0); sort(deep+1,deep+deep[0]+1); int l=1,r=deep[0]; for (;l<r;) if (deep[l]+deep[r]<=k){t+=r-l;l++;} else r--; return t; } void work(int x){ ans+=cal(x,0); vis[x]=1; for (int i=head[x];i;i=e[i].next){ int v=e[i].to; if (!vis[v]) { ans-=cal(v,e[i].w);sum=son[v];root=0; getroot(v,0); work(root); } } } int main(){ scanf("%d",&n); int u,v,w; for (int i=1;i<n;i++){ scanf("%d%d%d",&u,&v,&w); insert(u,v,w); insert(v,u,w); } f[0]=sum=n; scanf("%d",&k); getroot(1,0); work(root); printf("%d",ans); }
相关文章推荐
- 总是提示下载百度云管家的解决办法
- STL_算法_删除(unique、unique_copy)
- clover 显卡注入功能详细讲解
- layoutinflaterde 使用
- 安卓设置imageview变暗的效果,类似于qq离线状态
- cacti常见问题
- Android 内核之Android与Linux的关系
- Numpy的tile函数
- Spfa 模板
- 瀑布式开发、迭代开发、敏捷开发、XP与SCRUM的区别
- 【BZOJ2152】聪聪可可
- VS2010使用NuGet程序包管理器
- Java基础-实现文件搜索功能
- Java基础-实现文件搜索功能
- sublime插件安装
- 谷歌软件测试之道
- Linux学习之more命令
- python之路(五)-文件操作
- Divide and conquer:Median(POJ 3579)
- 生成二维码