zoukankan      html  css  js  c++  java
  • poj1741(树的点分治)

    题目连接:POJ - 1741

    看了好长时间才明白了点......

    网上讲解很多但感觉都不够详细。。。大概是太弱了吧-_-||

    学通了再回来写详解。。。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #define LL long long
      6 using namespace std;
      7 const int N=1e5+10;
      8 const int inf=1e9+10;
      9 int n,k;
     10 int rt,ans,sumnode,siz[N],vis[N],d[N];
     11 int dep[N]; //路径长度//dep[0]为子节点个数
     12 int f[N]; //重心
     13 struct edge
     14 {
     15     int v,w,nex;
     16 }e[N*2];
     17 int head[N];
     18 int cnt;
     19 void add(int u,int v,int w)
     20 {
     21     e[cnt].v=v;
     22     e[cnt].w=w;
     23     e[cnt].nex=head[u];
     24     head[u]=cnt++;
     25 }
     26 void getrt(int u,int fa) //找重心
     27 {
     28     siz[u]=1;
     29     f[u]=0;
     30     for(int i=head[u];i!=-1;i=e[i].nex)
     31     {
     32         int v=e[i].v;
     33         if(v==fa||vis[v]) continue;
     34         getrt(v,u);
     35         siz[u]+=siz[v];
     36         f[u]=max(f[u],siz[v]);
     37     }
     38     f[u]=max(sumnode-siz[u],f[u]);
     39     if(f[u]<f[rt]) rt=u;
     40 }
     41 
     42 void getdep(int u,int fa)  //获取子树所有节点与根的距离
     43 {
     44     dep[++dep[0]]=d[u];
     45     for(int i=head[u];i!=-1;i=e[i].nex)
     46     {
     47         int v=e[i].v;
     48         if(v==fa||vis[v]) continue;
     49         d[v]=d[u]+e[i].w;
     50         getdep(v,u);
     51     }
     52 }
     53 
     54 int cal(int u,int now) //计算当前以重心u为根的子树下所有情况的答案
     55 {
     56     d[u]=now;
     57     dep[0]=0;
     58     getdep(u,0);
     59     sort(dep+1,dep+dep[0]+1);
     60     int all=0;
     61     for(int l=1,r=dep[0];l<r;)
     62     {
     63         if(dep[l]+dep[r]<=k) {all+=r-l;l++;}
     64         else r--;
     65     }
     66     return all;
     67 }
     68 
     69 void work(int u) //以u为重心计算
     70 {
     71     vis[u]=1;
     72     ans+=cal(u,0);
     73     for(int i=head[u];i!=-1;i=e[i].nex)
     74     {
     75         int v=e[i].v;
     76         if(vis[v]) continue;
     77         ans-=cal(v,e[i].w);
     78         sumnode=siz[v];
     79         rt=0;
     80         getrt(v,u);
     81         work(rt);
     82     }
     83 }
     84 int u,v,w;
     85 int main()
     86 {
     87     while(scanf("%d%d",&n,&k)!=EOF)
     88     {
     89         if(!n&&!k) break;
     90         memset(head,-1,sizeof(head));
     91         memset(vis,0,sizeof(vis));
     92         cnt=0;
     93         for(int i=0;i<n-1;i++)
     94         {
     95             scanf("%d%d%d",&u,&v,&w);
     96             add(u,v,w);
     97             add(v,u,w);
     98         }
     99         rt=ans=0;
    100         sumnode=n;
    101         f[0]=inf;
    102         getrt(1,0);
    103         work(rt);
    104         printf("%d
    ",ans);
    105     }
    106 }
  • 相关阅读:
    547. Friend Circles
    399. Evaluate Division
    684. Redundant Connection
    327. Count of Range Sum
    LeetCode 130 被围绕的区域
    LeetCode 696 计数二进制子串
    LeetCode 116 填充每个节点的下一个右侧节点
    LeetCode 101 对称二叉树
    LeetCode 111 二叉树最小深度
    LeetCode 59 螺旋矩阵II
  • 原文地址:https://www.cnblogs.com/yijiull/p/6803738.html
Copyright © 2011-2022 走看看