poj 1741 Tree 点分治
来源:互联网 发布:淘宝互联软件是骗局吗 编辑:程序博客网 时间:2024/04/29 15:16
题目大意:
给定一棵N个节点、边上带权的树,再给出一个K,询问有多少个点对(u,v)满足dis[u,v]<=K。
数据规模:
给定一棵N个节点、边上带权的树,再给出一个K,询问有多少个点对(u,v)满足dis[u,v]<=K。
数据规模:
多组测试数据,N≤10000,1≤边权≤1000,1≤K≤10^9。
马克:楼天城男人必做8题之一.... 目前只做了这一题
http://wenku.baidu.com/view/60c6aa1ffc4ffe473368aba8.html
上面网址是讲解思路的论文,具体实现没说。。
首先是要找到重心,那么先递归求出每个点拆掉后能够得到的最大的点的个数,这个点的个数最小的肯定是重心。
然后就按照论文讲解的方法求点对数量,先要求出每个点到重心的距离。
下面是代码:#include <cstdio>#include <cstring>#include <string>#include <iostream>#include <algorithm>#include <queue>#include <map>#include <vector>using namespace std;const int MAXN = 10100;const int inf = 0x7f7f7f7f;typedef pair<int,int> PII;int n,k;int vis[MAXN],fa[MAXN];int mson[MAXN],son[MAXN];int nod[MAXN],ns;int dis[MAXN],ds;int ans;vector<PII >vv[MAXN];void dfs(int u,int p){ son[u]=1; mson[u]=0; nod[ns++]=u; int siz=vv[u].size(); for(int i=0;i<siz;i++) { int v=vv[u][i].first; if(vis[v]||v==p) continue; dfs(v,u); son[u]+=son[v]; mson[u]=max(mson[u],son[v]); }}int getroot(int u)//求重心{ ns=0; dfs(u,-1); int mi=MAXN,res=-1; for(int i=0;i<ns;i++) { mson[nod[i]]=max(mson[nod[i]],son[u]-son[nod[i]]);//每个点拆掉后能够得到的最大的点的个数 if(mson[nod[i]]<mi) { mi=mson[nod[i]]; res=nod[i]; } } return res;}void getdis(int u,int d,int p)//求出子节点到根的距离{ dis[ds++]=d; int siz=vv[u].size(); for(int i=0;i<siz;i++) { int v=vv[u][i].first; if(vis[v]||v==p) continue; getdis(v,d+vv[u][i].second,u); }}void calc(int u,int t) { sort(dis,dis+ds); int i=dis[0]?0:1,j=ds-1; while(i<j) { if(dis[i]+dis[j]<=k) { ans+=(j-i)*t; i++; } else j--; }}void solve(int u){ u=getroot(u); ds=0; getdis(u,0,-1); calc(u,1); //求以u为根的子节点可以构成多少对 vis[u]=1; for(int i=0;i<ds;i++) if(dis[i]<=k&&dis[i]!=0) ans++;//以根为起点的个数 int siz=vv[u].size(); for(int i=0;i<siz;i++) { int v=vv[u][i].first; if(vis[v]) continue; ds=0; getdis(v,vv[u][i].second,-1); calc(v,-1); //减去属于同一个子树的重复点对 solve(v); }}int main(){ while(~scanf("%d%d",&n,&k)&&(n||k)) { for(int i=0;i<=n;i++) vv[i].clear(); for(int i=1;i<n;i++) { int u,v,l; scanf("%d%d%d",&u,&v,&l); vv[u].push_back(make_pair(v,l)); vv[v].push_back(make_pair(u,l)); } ans=0; memset(vis,0,sizeof(vis)); solve(1); printf("%d\n",ans); }}
- 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
- POJ 1741 Tree 点分治
- poj 1741 Tree (点分治)
- POJ 1741 Tree 点分治
- POJ 1741 Tree【Tree,点分治】
- POJ 1741 Tree【Tree,点分治】
- poj 1741 Tree (点的分治)
- POJ 1741 Tree 树的点分治
- POJ 1741 Tree(树上的点分治)
- PP数据表
- Linux内核分析 - 网络[十四]:IP选项
- 大数据数据分析的大规模并行处理模型 Big Data Massive Parallel Processing(MPP) Model
- 数据库查询:查询在指定时间范围内的数据
- 联想触摸点和触摸板的禁用与解禁
- poj 1741 Tree 点分治
- 什么是tcp/ip
- 411. The grass is greener on the other side. 这山望着那山高
- setuid setgid and sticky bit详解
- TreeList的父节点展开和收缩子节点时,图标为“+”“—”
- androidUI设计之旅 ----TextView02
- http://blog.csdn.net/hejianhua/article/details/6670208
- JDBC开发
- js 获取屏幕信息