poj 1741 树的分治。。。。
队友给推荐了这道题。做了两天。看了题解的大概思路,结合自己原来的思路搞了一晚上总算A了。
链接:http://poj.org/problem?id=1741
代码:
#include<stdio.h>
#include<stdlib.h>
#include <algorithm>
#include<vector>
#define ma 10010
using namespace std;
int n,k;
typedef struct nod
{
int l,v;
}Node;
vector<Node> node[ma];
vector<int> len;
bool bu[ma];
int size,jude,sum;
int getsize(int x,int f)
{
int sum=1;
for(int i=0;i<node[x].size();i++)
{
int ans=node[x][i].l;
if(bu[ans]&&ans!=f)
{
sum+=getsize(ans,x);
}
}
return sum;
}
int getroot(int x,int f,int *root)
{
int max=0,ss=1,temp;
for(int i=0;i<node[x].size();i++)
{
int ans=node[x][i].l;
if(bu[ans]&&ans!=f)
{
temp=getroot(ans,x,root);
if(temp>max)max=temp;
ss+=temp;
}
}
if((size-ss)>max)max=size-ss;
if(max<jude){jude=max;*root=x;}
return ss;
}
void getd(int x,int f,int v)
{
len.push_back(v);
for(int i=0;i<node[x].size();i++)
{
int ans=node[x][i].l;
if(bu[ans]&&ans!=f)
{
getd(ans,x,v+node[x][i].v);
}
}
}
int con(int x,int limit)
{
len.clear();
getd(x,x,0);
sort(len.begin(),len.end());
int ll=0;
for(int l=0,r=len.size()-1;l<r;)
{
if(len[r]+len[l]<=k-2*limit)
{
ll+=(r-l);
l++;
}
else r--;
}
return ll;
}
void ff(int x)
{
sum+=con(x,0);
bu[x]=false;
for(int i=0;i<node[x].size();i++)
{
int ans=node[x][i].l;
if(bu[ans])
{
int root;
size=getsize(ans,ans);
jude=size;
sum-=con(ans,node[x][i].v);
getroot(ans,ans,&root);
ff(root);
}
}
}
int main()
{
Node nn;
while(scanf("%d%d",&n,&k)!=EOF)
{
if(!n&&!k)break;
for(int i=1;i<=n;i++)bu[i]=true;
for (int i=0; i<=n; i++)node[i].clear();
for(int i=1;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
nn.l=b;nn.v=c;
node[a].push_back(nn);
nn.l=a;
node[b].push_back(nn);
}
sum=0;
int root;
size=getsize(1,1);
jude=size;
getroot(1,1,&root);
ff(root);
printf("%d\n",sum);
}
return 0;
}