`
darren_nizna
  • 浏览: 71238 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

[PKU/POJ][1741][Tree][树的分治]

 
阅读更多

LTC 男人八题之一,解题报告见09看论文。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

int const N= 10010, inf= 0x7fffffff;
int n, k, cnt, tot, root, size, nchild, first, last, pre, ans;
int Fnum;

struct Edge{
	int adj, wt;
	Edge* next;
}tb[N<<1];

Edge* mat[N];
int dist[N], flag[N], que[N], vis[N], num[N];

void inline add( int u, int v, int d ){
	++cnt;
	tb[cnt].adj= v; tb[cnt].wt= d;
	tb[cnt].next= mat[u]; mat[u]= tb+ cnt;
	
	++cnt;
	tb[cnt].adj= u; tb[cnt].wt= d;
	tb[cnt].next= mat[v]; mat[v]= tb+ cnt;
}

int selectRoot( int rt ){
	flag[rt]= Fnum;
	
	int tmp= 0, sum= 0;
	for( Edge* p= mat[rt]; p; p= p->next ){
		int v= p->adj;
		
		if( vis[v]== 0 && flag[v]!= Fnum ){
			int s= selectRoot( v );
			
			if( s> tmp ) tmp= s;
			sum+= s;
		}
	}
	
	if( nchild- 1- sum> tmp ) tmp= nchild- 1- sum;
	
	if( tmp< size ){  size= tmp; root= rt; }
	
	return sum+ 1;
}

int inline getCount( int first, int last ){
	sort( dist+ first, dist+ last+ 1 );
	
	int head= first, tail= last, ret= 0;
	while( first< last ){
		if( dist[first]+ dist[last]<= k ) ret+= last- first++; 
		else last--;
	}
	return ret;
}

int dfs( int rt, int len ){
	flag[rt]= Fnum; dist[++last]= len;
	
	int sum= 0;
	for( Edge* p= mat[rt]; p; p= p->next )
	if( !vis[p->adj] && flag[p->adj]!= Fnum ){
		int v= p->adj, wt= p->wt;
		
		sum+= dfs( v, len+ wt );
	}
	
	num[rt]= sum+ 1;
	return sum+ 1;
}

void solve( int rt ){
	pre= 1;
	for( Edge* p= mat[rt]; p; p= p->next )
	if( !vis[p->adj] && flag[p->adj]!= Fnum ){
		int v= p->adj, wt= p->wt;
		
		dfs( v, wt );
		ans-= getCount( pre, last );

		pre= last+ 1;
	}
}

int main(){
	while( scanf("%d%d",&n,&k)!= EOF ){
		if( n== 0 && k== 0 ) return 0;
		
		for( int i= 0; i<= n; ++i ) mat[i]= 0, flag[i]= 0, vis[i]= 0;
		cnt= -1; tot= -1;
		
		int u, v, d;
		for( int i= 1; i< n; ++i ){
			scanf("%d%d%d", &u,&v,&d );
			
			add( u, v, d );
		}
		
		int head= 0, tail= 0; que[0]= 1; 
		nchild= n; ans= 0; Fnum= 0; num[1]= n;
		
		while( head<= tail ){
			int now= que[head++]; nchild= num[now]; Fnum++;
			
			size= 0x7fffffff; selectRoot( now ); vis[root]= 1;		
			
			for( Edge*p= mat[root]; p; p= p->next )
			if( !vis[p->adj] ) que[++tail]= p->adj;
			
			first= pre= 1; last= 0; Fnum++;
	
			solve( root ); dist[++last]= 0;
			ans+= getCount( first, last );
		}
		
		printf("%d\n", ans );
	}
	
	return 0;
}

 

0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics