码迷,mamicode.com
首页 > 其他好文 > 详细

poj 1741

时间:2015-08-19 12:44:18      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:

题意:求树上距离不超过k的点对数

解决:很经典的树分治

  1 //#include <bits/stdc++.h>
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <cstring>
  6 
  7 const int MAXN = 10000+10;
  8 
  9 struct Edge{
 10     int u, v, cost, next;
 11     Edge(){}
 12     Edge(int u, int v, int cost, int next)
 13     {
 14         this->u = u;
 15         this->v = v;
 16         this->cost = cost;
 17         this->next = next;
 18     }
 19 }edge[MAXN<<1];
 20 int tot;
 21 int head[MAXN];
 22 int dist[MAXN];
 23 int siz[MAXN];
 24 int max_sub[MAXN];
 25 int root;
 26 int res;
 27 bool vis[MAXN];
 28 int n, k;
 29 int min_max_siz;
 30 int sort_size;
 31 
 32 void addEdge(int u, int v, int cost)
 33 {
 34     edge[++tot] = Edge(u, v, cost, head[u]);
 35     head[u] = tot;
 36 }
 37 
 38 void init()
 39 {
 40     tot = 1;
 41     memset(head, 0, sizeof head);
 42     res = 0;
 43     memset(vis, false, sizeof vis);
 44 }
 45 
 46 void getRoot(int u, int fa, int r)
 47 {
 48     if (siz[r] - siz[u] > max_sub[u]) {
 49         max_sub[u] = siz[r] - siz[u];
 50     }
 51     if (min_max_siz > max_sub[u]) {
 52         min_max_siz = max_sub[u];
 53         root = u;
 54     }
 55     for (int i = head[u]; i > 0; i = edge[i].next) {
 56         int v = edge[i].v;
 57         if (v != fa && vis[v] == false) {
 58             getRoot(v, u, r);
 59         }
 60     }
 61 }
 62 
 63 void getSize(int u, int fa)
 64 {
 65     siz[u] = 1; max_sub[u] = 0;
 66     for (int i = head[u]; i > 0; i = edge[i].next) {
 67         int v = edge[i].v;
 68         if (v != fa && vis[v] == false) {
 69             getSize(v, u);
 70             siz[u] += siz[v];
 71             if (siz[v] > max_sub[u]) {
 72                 max_sub[u] = siz[v];
 73             }
 74         }
 75     }
 76 }
 77 
 78 void getDist(int u, int fa, int d)
 79 {
 80     dist[++sort_size] = d;
 81     for (int i = head[u]; i > 0; i = edge[i].next) {
 82         int v = edge[i].v;
 83         if (v != fa && vis[v] == false) {
 84             getDist(v, u, d + edge[i].cost);
 85         }
 86     }
 87 }
 88 
 89 int calc(int u, int d)
 90 {
 91     int ret = 0;
 92     sort_size = 0;
 93     getDist(u, 0, d);
 94     std::sort(dist+1, dist+1+sort_size);
 95     for (int i = 1; ; ++ i) {
 96         int val = k - dist[i];
 97         // get the first position where dist[pos] lager than val
 98         // then pos-1 is the right most position
 99         // where dist[pos-1] is less than or equal to val
100         int pos = std::upper_bound(dist+1, dist+sort_size+1, val) - dist;
101         -- pos;
102         if (pos <= i) {
103             break;
104         }
105         ret += (pos-i);
106     }
107     return ret;
108 }
109 
110 void dfs(int u)
111 {
112     min_max_siz = n;
113     // 1 array siz[]: sizes of all subtree
114     // 2 array sub_max[]: the max subtree of each node
115     getSize(u, 0);
116     //
117     getRoot(u, 0, u);
118     res += calc(root, 0);
119     vis[root] = true;
120     for (int i = head[root]; i > 0; i = edge[i].next) {
121         int v = edge[i].v;
122         if (vis[v] == false) {
123             res -= calc(v, edge[i].cost);
124             dfs(v);
125         }
126     }
127 
128 }
129 
130 int main()
131 {
132     while (~scanf("%d%d", &n, &k)) {
133         if(!(n||k)) {
134             break;
135         }
136         init();
137         for (int i = 1; i <= n-1; ++ i) {
138             int u, v, cost;
139             scanf("%d%d%d", &u, &v, &cost);
140             addEdge(u, v, cost);
141             addEdge(v, u, cost);
142         }
143         dfs(1);
144         printf("%d\n", res);
145     }
146     return 0;
147 }

 

poj 1741

标签:

原文地址:http://www.cnblogs.com/takeoffyoung/p/4741754.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!