POJ 1741(男人八题-Tree-点分治)
来源:互联网 发布:office for mac汉化包 编辑:程序博客网 时间:2024/06/06 05:57
Language:
Tree
Time Limit: 1000MS Memory Limit: 30000KTotal Submissions: 6982 Accepted: 2010
Description
给定一棵 N (1≤ N≤ 10000) 个结点的带权(≤1000)树,定义 dist(u, v) 为 u, v 两点间的最短路径长度, 路径的长度定义为路径上所有边的权和。再给定一个 K (1≤ K≤ 10 ) ,如果对于不同的两个结点 a, b ,如果满 足 dist (a, b)≤ K ,则称 (a, b) 为合法点对。 求合法点对个数。
Input
有很多数据. 每组数据第一行为 n, k. (n<=10000) 接下来 n-1 行为 u,v,w, 表示u和v之间有一条权为w的边.
数据以‘0 0’结尾.
数据以‘0 0’结尾.
Output
对每组数据输出一行合法点对个数.
Sample Input
5 41 2 31 3 11 4 23 5 10 0
Sample Output
8
Source
LouTiancheng@POJ
在漆子超的论文里有该题的详细解题报告。
在这里简单说说树链剖分中center_node的选取。
center_node为一棵子树中的一个能使其为根节点时,其的子树的最大结点数最小的的结点。
也就是使子树的max_siz最小
因为换了root,必须用b记录,防止走到子树外去。
重儿子:一个节点的儿子中siz最大的那个(hson)
#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<iostream>#include<functional>#include<algorithm>using namespace std;#define MAXN (10000+10)int n,k;int edge[MAXN*2],pre[MAXN],next[MAXN*2],weight[MAXN*2],size=0;bool b[MAXN];void addedge(int u,int v,int w){edge[++size]=v;weight[size]=w;next[size]=pre[u];pre[u]=size;}int dis[MAXN],deep[MAXN],siz[MAXN],max_sub_siz[MAXN],tot;int que[MAXN],q_n;void get_center_dfs(int u,int fa){siz[u]=1;que[++q_n]=u;max_sub_siz[u]=0;for (int p=pre[u];p;p=next[p]){int &v=edge[p];if (v!=fa&&!b[v]){get_center_dfs(v,u);siz[u]+=siz[v];max_sub_siz[u]=max(max_sub_siz[u],siz[v]);}}}int get_center(int u,int fa){int minhson=n,mini=0;q_n=0;get_center_dfs(u,fa);for (int i=1;i<=q_n;i++){max_sub_siz[que[i]]=max(max_sub_siz[que[i]],q_n-siz[que[i]]);if (minhson>max_sub_siz[que[i]]){minhson=max_sub_siz[que[i]];mini=que[i];}}return mini;}void getdis(int u,int d,int fa){dis[++tot]=d;for (int p=pre[u];p;p=next[p]){int &v=edge[p];if (v!=fa&&!b[v]){getdis(v,d+weight[p],u);}}}int count_dis(int l,int r){int i=l,j=r,ans=0;sort(dis+l,dis+r+1);while (i<j){if (dis[i]+dis[j]<=k) ans+=j-(i++);else j--;}return ans;}int dfs_main(int u,int fa){int root=get_center(u,fa),ans=0;tot=0;b[root]=1;for (int p=pre[root];p;p=next[p]) //root{int &v=edge[p];if (v!=fa&&!b[v]){int l=tot+1;getdis(v,weight[p],root);ans-=count_dis(l,tot);}}dis[++tot]=0;ans+=count_dis(1,tot);for (int p=pre[root];p;p=next[p]){int &v=edge[p];if (v!=fa&&!b[v]){ans+=dfs_main(v,root);}}return ans;}int main(){//freopen("poj1741.in","r",stdin);while (scanf("%d%d",&n,&k)&&(n+k)){memset(pre,0,sizeof(pre));size=0;memset(b,0,sizeof(b));int u,v,w;for (int i=1;i<n;i++){scanf("%d%d%d",&u,&v,&w);addedge(u,v,w);addedge(v,u,w);}cout<<dfs_main(edge[1],0)<<endl;}return 0;}
- POJ 1741(男人八题-Tree-点分治)
- POJ 1741 Tree (树上点分治)(楼教主男人八题之一)
- POJ 1741 Tree(树的点分治、树形dp、男人八题)
- POJ:1741 Tree(男人八题-树分治)
- POJ 1741 Tree(树分治|ltc男人八题)
- poj 1741 Tree 据说是男人八题
- POJ 1741 Tree (男人八题
- poj 1741 楼教主男人八题之一:树分治
- poj 1741 Tree 点分治
- 【POJ 1741】 Tree --点分治
- 【POJ】1741 Tree 点分治
- 【POJ】1741 Tree 点分治
- poj 1741 Tree 点分治
- POJ 1741 Tree 点分治
- poj 1741 Tree 点分治
- POJ 1741 Tree 点分治
- poj 1741Tree(点分治)
- 点分治 POJ 1741 Tree
- 简单数据结构实现——双链表
- 利用Xmarks进行Chrome和Safari书签的同步
- [SSP]HTTP权威指南——HTTP报文(下)
- 30个漂亮的免费 Flash 网站模板下载
- 跟我一起学习ASP.NET 4.5 MVC4.0(六)
- POJ 1741(男人八题-Tree-点分治)
- 最新10款好看的英文字体下载
- 12款很棒的浏览器兼容性测试工具推荐
- 最短路径算法详解
- 采用commons-configuration包实现属性文件读取的工具类
- [Linux] Linux 常用操作命令
- 迭代器(iterator)与逆向迭代器(reverse_iterator)的转换
- 【CodeBlocks 非官方翻译】项目主页
- wget中文乱码解决方案