记录编号 166979 评测结果 AAAAAAAAAA
题目名称 [POJ1741][男人八题]树上的点对 最终得分 100
用户昵称 GravatarHouJikan 是否通过 通过
代码语言 C++ 运行时间 1.588 s
提交时间 2015-06-18 10:16:15 内存使用 57.83 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <functional>
#include <vector>
#include <map>
#include <string>
#include <queue>
#include <stack>
using namespace std;
typedef long long LL;
///===================struct declaration======================
struct adj{
	 int to,dist;
	 adj (int to = 0, int dist = 0): to(to), dist(dist){}
};
///===================var declaration=========================
const int MAXN=10010;
int n,k,_Ans,_Sum,SubTreeSize;
int Depth[MAXN],S[MAXN],f[MAXN],A[MAXN * 1500];
bool Del[MAXN];
vector <adj> Edge[MAXN];
///===================function declaration====================
void GetAns(int x);//得出x所在的子树中的答案
void DFS(int x, int fa, int &Sub);//得出depth等信息
void DFS2(int x, int fa, vector <int> &List);//用于合并子树信息
void dp(int x, int fa, int &core);
int Query(int x);int lowbit(int x){return x & -x;}void Add(int x, int Val);
///===================main code===============================
int main(){

	 freopen("poj1741_tree.in","r",stdin);
	 freopen("poj1741_tree.out","w",stdout);

 	 while (scanf("%d%d", &n, &k) != EOF && n){
		  _Ans = 0;memset(Del, false, sizeof(Del));
		  for (int i = 1; i <= n; i++)  Edge[i].clear();
		  for (int i = 1; i < n; i++){
				int u, v, l;scanf("%d%d%d", &u, &v, &l);
				Edge[u].push_back(adj(v, l));
				Edge[v].push_back(adj(u, l));
		  }
		  GetAns(1);
		  printf("%d\n", _Ans);
	 }
	 return 0;
}
///==================function code===========================
void GetAns(int x){
	 Depth[x] = 0;
	 DFS(x, -1, SubTreeSize = 0);
	 f[0] = 1008611;
	 int core = 0;
	 dp(x, -1, core);
	 Depth[core] = 0;
	 DFS(core, -1, SubTreeSize = 0);
	 int siz = Edge[core].size();
	 vector <int> LIST;
	 for(int i = 0; i < siz; i++){
		  adj &e = Edge[core][i];
		  if (Del[e.to]) continue;
		  vector <int> List;List.clear();
		  DFS2(e.to, core, List);
		  int ListSize = List.size();
		  for(int j = 0; j < ListSize; j++){
				Add(List[j], 1);
				LIST.push_back(List[j]);
		  }
	 }
	 int LISTSize = LIST.size();
	 for(int i = 0; i <  LISTSize; i++)
		  Add(LIST[i], -1);
	 Del[core] = true;
	 for(int i = 0; i < siz; i++){
		  adj &e = Edge[core][i];
		  if (Del[e.to]) continue;
		  GetAns(e.to);
	 }
}
void DFS(int x, int fa, int &Sub){
	 int siz = Edge[x].size();
	 S[x] = 1;
	 if (x == 7403){
		  int a = 0 ;
		  a++;
	 }
	 Sub ++;
	 for (int i = 0; i < siz; i++){
		  adj &e = Edge[x][i];
		  if (e.to == fa || Del[e.to]) continue;
		  Depth[e.to] = Depth[x] + e.dist;
		  DFS(e.to, x, Sub);
		  S[x] += S[e.to];
	 }
}
void dp(int x, int fa, int &core){
	 int siz = Edge[x].size();
	 f[x] = SubTreeSize - S[x];
	 for (int i = 0; i < siz; i++){
		  adj &e = Edge[x][i];
		  if (Del[e.to] || e.to == fa) continue;
		  dp(e.to, x, core);
		  f[x] = max(f[x], S[e.to]);
	 }
	 if (f[x] < f[core]) core = x;
}
void DFS2(int x, int fa, vector <int> &List){
	 if (Depth[x] > k) return;
	 _Ans ++;
	 List.push_back(Depth[x]);
	 _Ans += Query(k - Depth[x]);
	 int siz = Edge[x].size();
	 for(int i = 0; i < siz; i++){
		  adj &e = Edge[x][i];
		  if (e.to == fa || Del[e.to]) continue;
		  DFS2(e.to, x, List);
	 }
}
int Query(int x){
	 int res = 0;
	 while (x > 0){
		  res += A[x];
		  x -= lowbit(x);
	 }
	 return res;
}
void Add(int x, int Val){
	 while (x <= k){
		  A[x] += Val;
		  x += lowbit(x);
	 }
}