C++之路进阶——bzoj1468(tree)
F.A.Qs | Home | Discuss | ProblemSet | Status | Ranklist | Contest | ModifyUser gryz2016 | Logout | 捐赠本站 |
---|
Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入、输出语句及数据类型及范围,避免无谓的RE出现。
1468: Tree
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 774 Solved: 412
[Submit][Status][Discuss]
Description
给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K
Input
N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是k
Output
一行,有多少对点之间的距离小于等于k
Sample Input
7
1 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10
1 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10
Sample Output
5
HINT
题解:
点分。。。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #define maxn 400100 5 6 using namespace std; 7 8 int n,m,root,sum,ans,cnt,head[maxn],son[maxn],f[maxn],vis[maxn],deep[maxn],d[maxn]; 9 10 struct ss 11 { 12 int to; 13 int next; 14 int w; 15 }e[maxn]; 16 17 void insert(int u,int v,int w) 18 { 19 e[++cnt].to=v; e[cnt].next=head[u]; e[cnt].w=w; head[u]=cnt; 20 e[++cnt].to=u; e[cnt].next=head[v]; e[cnt].w=w; head[v]=cnt; 21 } 22 23 void getroot(int x,int fa) 24 { 25 son[x]=1; 26 f[x]=0; 27 for (int i=head[x];i;i=e[i].next) 28 if (!vis[e[i].to]&&e[i].to!=fa) 29 { 30 getroot(e[i].to,x); 31 son[x]+=son[e[i].to]; 32 f[x]=max(f[x],son[e[i].to]); 33 } 34 f[x]=max(f[x],sum-son[x]); 35 if (f[x]<f[root]) root=x; 36 } 37 38 void getdeep(int x,int fa) 39 { 40 deep[++deep[0]]=d[x]; 41 for (int i=head[x];i;i=e[i].next) 42 if (!vis[e[i].to]&&e[i].to!=fa) 43 { 44 d[e[i].to]=d[x]+e[i].w; 45 getdeep(e[i].to,x); 46 } 47 } 48 49 int cal(int x,int now) 50 { 51 d[x]=now; 52 deep[0]=0; 53 getdeep(x,0); 54 sort(deep+1,deep+deep[0]+1); 55 int t=0,l,r; 56 for(l=1,r=deep[0];l<r;) 57 { 58 if(deep[l]+deep[r]<=m){t+=r-l;l++;} 59 else r--; 60 } 61 return t; 62 } 63 64 void work(int x) 65 { 66 ans+=cal(x,0); 67 vis[x]=1; 68 for (int i=head[x];i;i=e[i].next) 69 if(!vis[e[i].to]) 70 { 71 ans-=cal(e[i].to,e[i].w); 72 sum=son[e[i].to]; 73 root=0; 74 getroot(e[i].to,root); 75 work(root); 76 } 77 } 78 79 int main() 80 { 81 scanf("%d",&n); 82 for (int i=1;i<n;i++) 83 { 84 int u,v,w; 85 scanf("%d%d%d",&u,&v,&w); 86 insert(u,v,w); 87 } 88 scanf("%d",&m); 89 sum=n; 90 f[0]=0x7fffffff; 91 getroot(1,0); 92 work(1); 93 printf("%d",ans); 94 }