1. [POJ1741][男人八题]树上的点对

    ★★★ 输入文件:poj1741_tree.in 输出文件:poj1741_tree.out 简单对比

    时间限制:1 s 内存限制:256 MB

    【题目描述】

    给一棵有n个节点的树,每条边都有一个长度(小于1001的正整数)。

    定义dist(u,v)=节点u到节点v的最短路距离。

    给出一个整数k,我们称顶点对(u,v)是合法的当且仅当dist(u,v)不大于k。

    写一个程序,对于给定的树,计算有多少对顶点对是合法的。

    【输入格式】

    输入包含多组数据。

    每组数据的第一行有两个整数N,K(N<=10000)。接下来N-1行每行有三个整数u,v,l,代表节点u和v之间有一条长度l的无向边。

    输入结束标志为N=K=0.

    【输出格式】

    对每组数据输出一行一个正整数,即合法顶点对的数量。

    【样例输入】

    5 4

    1 2 3

    1 3 1

    1 4 2

    3 5 1

    0 0

    【样例输出】

    8

    【来源】

    **POJ 1741 Tree

    男人八题 Problem E**
/*
乱搞80分2333.
T了.
处理出每个树的贡献,再减去在每颗子树中的贡献.
可能是让链卡掉了QWQ.
每个点至多有logn个父亲.
也就是在logn个子树中.
复杂度应该是O(Nlogn2)的.
如果是链的话就变成了O(N^2).
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAXN 10001
using namespace std;
int n,k,tot,ans,cut,dis[MAXN],maxsize,s[MAXN],a[MAXN],pos[MAXN],end[MAXN],fa[MAXN],head[MAXN],deep[MAXN],size[MAXN];
struct edge{int v,next,x;}e[MAXN*2];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void add(int u,int v,int x)
{
e[++cut].v=v;e[cut].x=x;e[cut].next=head[u];head[u]=cut;
}
void dfs(int u)
{
s[++maxsize]=dis[u];pos[u]=maxsize;
for(int i=head[u];i;i=e[i].next)
{
if(!fa[e[i].v])
deep[e[i].v]=deep[u]+1,
fa[e[i].v]=u,dis[e[i].v]=dis[u]+e[i].x,dfs(e[i].v);
}
end[u]=maxsize;
return ;
}
int erfen(int l,int r)
{
int total=0;
while(l<r)
{
if(a[l]+a[r]<=k) total+=r-l,l++;
else r--;
}
return total;
}
int get(int u,int d)
{
int sum=0;tot=0;
for(int i=pos[u];i<=end[u];i++) a[++tot]=s[i]-dis[u]+d;
sort(a+1,a+tot+1);
return erfen(1,tot);
}
void get_dis(int u)
{
ans+=get(u,0);
for(int i=head[u];i;i=e[i].next)
if(fa[e[i].v]==u) ans-=get(e[i].v,e[i].x),get_dis(e[i].v);
return ;
}
void slove()
{
fa[1]=1;dfs(1);
for(int i=1;i<=n;i++) a[i]=s[i];
sort(a+1,a+n+1);
ans+=erfen(1,n);
for(int i=head[1];i;i=e[i].next)
if(fa[e[i].v]==1) ans-=get(e[i].v,e[i].x),get_dis(e[i].v);
return ;
}
void Clear()
{
memset(head,0,sizeof head);
memset(fa,0,sizeof fa);
cut=maxsize=tot=ans=0;
}
int main()
{
freopen("poj1741_tree.in","r",stdin);
freopen("poj1741_tree.out","w",stdout);
int x,y,z;
while(true)
{
Clear();n=read(),k=read();
if(!n&&!k) break;
for(int i=1;i<=n-1;i++)
{
x=read(),y=read(),z=read();
add(x,y,z),add(y,x,z);
}
slove();
printf("%d\n",ans);
}
return 0;
}
/*
点分治.
找树的重心.
第一次打,抄的黄学长的.
重心是使得与该点相邻的联通块点数
最大的最小化的那个点.
显然如果用一颗树的重心作根的话,
可以使子树最大的最小化.
复杂度应该是O(Nlogn2)的.
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAXN 10001
using namespace std;
int n,k,tot,ans,cut,f[MAXN],sum,root,dis[MAXN],maxsize,a[MAXN],head[MAXN],deep[MAXN],size[MAXN];
bool b[MAXN];
struct edge{int v,next,x;}e[MAXN*2];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void add(int u,int v,int x)
{
e[++cut].v=v;e[cut].x=x;e[cut].next=head[u];head[u]=cut;
}
int erfen(int l,int r)
{
int total=0;
while(l<r)
{
if(a[l]+a[r]<=k) total+=r-l,l++;
else r--;
}
return total;
}
void get_root(int u,int fa)
{
size[u]=1;f[u]=0;
for(int i=head[u];i;i=e[i].next)
{
if(e[i].v==fa||b[e[i].v]) continue;
get_root(e[i].v,u);
size[u]+=size[e[i].v];
f[u]=max(f[u],size[e[i].v]);
}
f[u]=max(f[u],sum-size[u]);//u上方的联通块.
if(f[u]<f[root]) root=u;
}
void get_deep(int u,int fa)
{
a[++tot]=dis[u];
for(int i=head[u];i;i=e[i].next)
{
if(e[i].v==fa||b[e[i].v]) continue;
dis[e[i].v]=dis[u]+e[i].x;
get_deep(e[i].v,u);
}
return ;
}
int get(int u,int d)
{
dis[u]=d;tot=0;
get_deep(u,0);
sort(a+1,a+tot+1);
return erfen(1,tot);
}
void slove(int u)
{
b[u]=true;ans+=get(u,0);
for(int i=head[u];i;i=e[i].next)
{
if(b[e[i].v]) continue;
ans-=get(e[i].v,e[i].x);
sum=size[e[i].v];
root=0;
get_root(e[i].v,root);
slove(root);
}
return ;
}
void Clear()
{
memset(head,0,sizeof head);
memset(b,0,sizeof b);
memset(f,0,sizeof f);
root=cut=maxsize=tot=ans=0;
}
int main()
{
freopen("poj1741_tree.in","r",stdin);
freopen("poj1741_tree.out","w",stdout);
int x,y,z;
while(true)
{
Clear();n=read(),k=read();
if(!n&&!k) break;
for(int i=1;i<=n-1;i++)
{
x=read(),y=read(),z=read();
add(x,y,z),add(y,x,z);
}
f[0]=1e9;
sum=n,get_root(1,root);
slove(root);
printf("%d\n",ans);
}
return 0;
}

Cogs 1714. [POJ1741][男人八题]树上的点对(点分治)的更多相关文章

  1. poj 1741 楼教主男人八题之中的一个:树分治

    http://poj.org/problem? id=1741 Description Give a tree with n vertices,each edge has a length(posit ...

  2. poj 1737男人八题之一 orz ltc

    这是楼教主的男人八题之一.很高兴我能做八分之一的男人了. 题目大意:求有n个顶点的连通图有多少个. 解法: 1.  用总数减去不联通的图(网上说可以,我觉得时间悬) 2.    用动态规划(数学递推) ...

  3. POJ1742 Coins(男人八题之一)

    前言 大名鼎鼎的男人八题,终于见识了... 题面 http://poj.org/problem?id=1742 分析 § 1 多重背包 这很显然是一个完全背包问题,考虑转移方程: DP[i][j]表示 ...

  4. 新男人八题---AStringGame

    终于完成进度男人1/8,为了这题学了sam= = 题意先有一个串,n个子串,两个人轮流每次在子串上加字符,要求加完后还是原串的子串,最后不能加的就是输者,求赢的人 解法:sam之后在构造的状态图上跑s ...

  5. poj 1742(好题,楼天城男人八题,混合背包)

    Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 33269   Accepted: 11295 Descripti ...

  6. 博弈论(男人八题):POJ 1740 A New Stone Game

    A New Stone Game Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5694   Accepted: 3119 ...

  7. poj 1743 男人八题之后缀数组求最长不可重叠最长重复子串

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 14874   Accepted: 5118 De ...

  8. nyoj137 取石子(三) 楼教主男人八题之一

    思路:一堆时,N态.两堆时,当两堆数量相同,P态,不同为N态.三堆时,先手可以变成两堆一样的,必胜N态. 此时可以总结规律:堆数为偶数可能且石子数都是两两相同的,为P态.分析四堆时,当四堆中两两数量一 ...

  9. 某模拟赛C题 树上路径统计 (点分治)

    题意 给定一棵有n个节点的无根树,树上的每个点有一个非负整数点权.定义一条路径的价值为路径上的点权和-路径上的点权最大值. 给定参数P,我!=们想知道,有多少不同的树上简单路径,满足它的价值恰好是P的 ...

随机推荐

  1. Ajax跨越请求失败,解决

    跨越请求 1.1什么是跨域(两个不同系统之间的访问.调用) (1)域名不同,即两个不同的应用. (2)域名相同,但是端口不同,即同一个应用中的不同子系统. 1.2 Ajax跨域请求的缺陷 (1)创建t ...

  2. stm32f103re stop模式下降低功耗

    一端口设置1.将N.C的GPIO统一配置为GPIO_Mode_AIN: 2.检查输入引脚,按照不工作时候的状态相应配置为  IPD/IPU,即避免在内部上/下拉电阻上消耗电流,而且该电流理论值为VCC ...

  3. markdown语法之列表与缩进

    在markdown语法中, 用*或+或-在行首表示无序列表.在这些符号之后应该空一格然后输入内容. 例如 + 无序列表 * 无序列表 - 无序列表 会被markdown语法渲染为 无序列表 列表嵌套 ...

  4. VBA分别使用MSXML的DOM属性和XPATH进行网页爬虫

    本文要重点介绍的是VBA中的XmlHttp对象(MSXML2.XMLHTTP或MSXML.XMLHTTP),它可以向http服务器发送请求并使用微软XML文档对象模型Microsoft XML Doc ...

  5. 基于【 SpringBoot】一 || QQ授权流程

    一.准备工作 1.qq开放平台应用申请,获取APP ID和APP Key 2.qq开放平台配置回调地址 二.服务器端生成授权链接 1.请求地址 https://graph.qq.com/oauth2. ...

  6. Map和TreeMap的特点

    Map的特点: 将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 TreeMap的特点: 无序,不允许重复(无序指元素顺序与添加顺序不一致) TreeMap集合默认会对键进行排 ...

  7. 总结一下几个for循环常见用法和区别

    1.for循环//有人喜欢使用一个临时变量把长度缓存起来,说是数据量大时效果更好(我本人没有去验证) for(j = 0,len=arr.length; j < len; j++) { //执行 ...

  8. window.postMessage()实现(iframe嵌套页面)跨域消息传递

    window.postMessage()方法可以安全地实现Window对象之间的跨域通信.例如,在页面和嵌入其中的iframe之间. 不同页面上的脚本允许彼此访问,当且仅当它们源自的页面共享相同的协议 ...

  9. MIG(ddr3)工程报错解决:IO constraint DQS_BIAS\Multiple Driver Net

    现象 在布线自己写的ddr3压力测试代码时,报如下错误. [Constraints 18-586]IO constraint DQS_BIAS with a setting of TRUE for c ...

  10. K2 BPM_加班党们,说好不哭还是说好不秃?_流程管理

    早上经过财务小陈的办公桌 看到她正边看手机边默默流泪 诶?这不是这两天刷屏的 周杰伦的<说好不哭>吗 小陈你怎么哭啦,这歌让你想到前男友了吗? ...... (摇头) 小陈擦擦眼泪 唱起了 ...