博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 1741 Tree(树形DP+分治)难
阅读量:4036 次
发布时间:2019-05-24

本文共 3916 字,大约阅读时间需要 13 分钟。

1、

2、题目大意:

给一棵树,dist(u,v)是指的uv两个顶点之间的最短距离,现在给出一个k值,

求在这棵树上有多少对(u,v)满足dist(u,v)<=k

如果uv在同一个分支上,那么dist(u,v)就死uv间的距离,如果uv不在同一个分支上,那么他们之间的最短距离就等于他们到最近的公共父节点的距离之和。

这道题目如果用dfs搜索每一个根节点得用n*n的时间,会超时,看介绍的需要用到分治,

3、题目

Tree
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 8667   Accepted: 2591

Description

Give a tree with n vertices,each edge has a length(positive integer less than 1001).
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.

Input

The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
The last test case is followed by two zeros.

Output

For each test case output the answer on a single line.

Sample Input

5 41 2 31 3 11 4 23 5 10 0

Sample Output

8

AC代码参考

#include 
#include
#include
using namespace std;#define MAX 21000#define INF 2147483647#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)struct node { int v, len; //v表示邻接点,len表示边权 int sum, bal; //sum表示子孙节点个数,bal表示拆当前点后子树的最大结点数 node *next;} tree[MAX], *head[MAX], tp[MAX];int n, ptr, ans, root;int tot, k, dist[MAX], vis[MAX];int size[MAX], sign[MAX]; //size表示最大分支的结点数,sign是一个hash数组void Initial() { ans = ptr = 0; for (int i = 0; i < MAX; ++i) vis[i] = 0,head[i] = NULL;}void AddEdge(int a, int b, int c) { tree[ptr].v = b, tree[ptr].len = c; tree[ptr].next = head[a], head[a] = &tree[ptr++];}void Dfs(int s, int pa) { tp[s].sum = tp[s].bal = 0; node *p = head[s]; while (p != NULL) { if (p->v != pa && vis[p->v] == 0) {//在哪赋值成1??? Dfs(p->v, s); tp[s].sum += tp[p->v].sum; //累计子节点个数 tp[s].bal = max(tp[s].bal, tp[p->v].sum); //找最大分支 } p = p->next; } tp[s].sum++; //自己 sign[tot] = s; //hash size[tot++] = tp[s].bal; //记录每个最大分支的结点数}int GetRoot(int s) { tot = 0, Dfs(s, 0); int maxx = INF, maxi, cnt = tp[s].sum; for (int i = 0; i < tot; ++i) { size[i] = max(size[i], cnt - size[i]); if (size[i] < maxx) { maxx = size[i]; maxi = sign[i]; } } return maxi;}void GetDist(int s, int pa, int dis) { //保存每个结点到根节点的距离 node *p = head[s]; dist[tot++] = dis; while (p != NULL) { if (p->v != pa && vis[p->v] == 0 && dis + p->len <= k) GetDist(p->v, s, dis + p->len); p = p->next; }}void Count1(int s) { sort(dist, dist + tot); int left = 0, right = tot - 1; while (left < right) { if (dist[left] + dist[right] <= k) ans += right - left, left++; else right--; }}void Count2(int s) { vis[s] = 1; node *p = head[s]; while (p != NULL) { if (vis[p->v] == 0) { tot = 0, GetDist(p->v, s, p->len); sort(dist, dist + tot); int left = 0, right = tot - 1; while (left < right) { if (dist[left] + dist[right] <= k) ans -= right - left, left++; else right--; } } p = p->next; }}void Solve(int s, int pa) { root = GetRoot(s); tot = 0,GetDist(root, 0, 0); Count1(root); Count2(root); // ans += count1 - coutn2; node *p = head[root]; while (p != NULL) { if (p->v != pa && vis[p->v] == 0) Solve(p->v, root); p = p->next; }}int main(){ int i, j, a, b, c; while (scanf("%d%d", &n, &k),n + k) { Initial(); for (i = 1; i < n; ++i) { scanf("%d%d%d", &a, &b, &c); AddEdge(a, b, c); AddEdge(b, a, c); } Solve(1, 0); printf("%d\n", ans); }}

 

 

转载地址:http://drddi.baihongyu.com/

你可能感兴趣的文章
Maven项目版本继承 – 我必须指定父版本?
查看>>
Maven跳过单元测试的两种方式
查看>>
通过C++反射实现C++与任意脚本(lua、js等)的交互(二)
查看>>
利用清华镜像站解决pip超时问题
查看>>
[leetcode BY python]1两数之和
查看>>
微信小程序开发全线记录
查看>>
Centos import torchvision 出现 No module named ‘_lzma‘
查看>>
PTA:一元多项式的加乘运算
查看>>
CCF 分蛋糕
查看>>
解决python2.7中UnicodeEncodeError
查看>>
小谈python 输出
查看>>
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
查看>>
python:如何将excel文件转化成CSV格式
查看>>
Django 的Error: [Errno 10013]错误
查看>>
机器学习实战之决策树(一)
查看>>
机器学习实战之决策树二
查看>>
[LeetCode By Python]7 Reverse Integer
查看>>
[leetCode By Python] 14. Longest Common Prefix
查看>>
[leetCode By Python]111. Minimum Depth of Binary Tree
查看>>
[LeetCode By Python]118. Pascal's Triangle
查看>>