POJ_P1741 Tree(树上点分治)

来源:互联网 发布:中央网络电视台 编辑:程序博客网 时间:2024/05/16 07:58

POJ传送门
Tree
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 15965 Accepted: 5205
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 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0

Sample Output
8

Source
LouTiancheng@POJ

论文题

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<iostream>using namespace std;#define N 10009 inline int in(int x=0,int v=1,char ch=getchar()){    while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();if(ch=='-') v=-1,ch=getchar();    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*v;}struct Node{int v,l;};vector<Node> g[N];int n,k,ans,sz,root,s[N],d[N],f[N];bool b[N];vector<int> deep;void GetRoot(int u,int fa){    s[u]=1,f[u]=0;int lim=g[u].size();    for(int i=0,v;i<lim;i++)        if((v=g[u][i].v)!=fa&&!b[v])            GetRoot(v,u),s[u]+=s[v],f[u]=max(f[u],s[v]);    f[u]=max(f[u],sz-s[u]);if(f[u]<f[root]) root=u;}void GetDeep(int u,int fa){    deep.push_back(d[u]),s[u]=1;int lim=g[u].size();    for(int i=0,v;i<lim;i++)        if((v=g[u][i].v)!=fa&&!b[v])            d[v]=d[u]+g[u][i].l,GetDeep(v,u),s[u]+=s[v];}int Calc(int u,int w,int res=0){    deep.clear(),d[u]=w;GetDeep(u,0);    sort(deep.begin(),deep.end());    for(int l=0,r=deep.size()-1;l<r;)        if(deep[l]+deep[r]<=k) res+=r-l,l++;        else r--;    return res;}void GetAns(int u){    ans+=Calc(u,0),b[u]=1;int lim=g[u].size();    for(int i=0,v;i<lim;i++)        if(!b[v=g[u][i].v])            ans-=Calc(v,g[u][i].l),f[0]=sz=s[u],            GetRoot(v,root=0),GetAns(root);}inline void init(){memset(b,0,sizeof(b));for(int i=0;i<=n;i++) g[i].clear();    f[0]=sz=n,root=ans=0;}int main(){    while(scanf("%d%d",&n,&k)!=EOF&&(n&&k)){        init();        for(int i=1,x,y,z;i<n;i++)            x=in(),y=in(),z=in(),            g[x].push_back((Node){y,z}),            g[y].push_back((Node){x,z});        GetRoot(1,root);GetAns(root);        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击