• 「POJ1741」Tree


    点分治

    感觉像线性数据结构上的二分

    或者说线性数据结构上的二分就是点分治的特殊情况

     1 #include<cstdio> 
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=10010,oo=INT_MAX;
     7 int n,maxd,ans;
     8 struct Edge{
     9     int to,len,nxt;
    10     Edge(int _to=0,int _len=0,int _nxt=0):to(_to),len(_len),nxt(_nxt){}
    11 }edge[N<<1];
    12 int last[N],edge_tot;
    13 int siz[N],root,f[N],tot,dep[N],dep_tot;
    14 bool vis[N];
    15 void add_edge(int f,int t,int l){
    16     edge[++edge_tot]=Edge(t,l,last[f]);
    17     last[f]=edge_tot;
    18     return;
    19 }
    20 void getroot(int k,int fa){
    21     siz[k]=1,f[k]=0;
    22     for(int i=last[k];i;i=edge[i].nxt){
    23         if(edge[i].to==fa||vis[edge[i].to]) continue;
    24         getroot(edge[i].to,k);
    25         siz[k]+=siz[edge[i].to];
    26         f[k]=max(f[k],siz[edge[i].to]);
    27     }
    28     f[k]=max(f[k],tot-siz[k]);
    29     if(f[k]<f[root]) root=k;
    30     return;
    31 }
    32 void dfs(int k,int fa,int d){
    33     dep[++dep_tot]=d;
    34     for(int i=last[k];i;i=edge[i].nxt){
    35         if(edge[i].to==fa||vis[edge[i].to]) continue;
    36         dfs(edge[i].to,k,d+edge[i].len);
    37     }
    38     return;
    39 }
    40 int calc(int k,int d){
    41     dep_tot=0;dfs(k,0,d);
    42     sort(dep+1,dep+dep_tot+1);
    43     int l=1,r=dep_tot,res=0;
    44     for(l;l<r;l++){
    45         while(l<r&&dep[r]+dep[l]>maxd) r--;
    46         res+=r-l;
    47     }
    48     return res;
    49 }
    50 void work(int k){
    51     vis[k]=1;
    52     ans+=calc(k,0);
    53     for(int i=last[k];i;i=edge[i].nxt){
    54         if(vis[edge[i].to]) continue;
    55         ans-=calc(edge[i].to,edge[i].len);
    56         tot=siz[edge[i].to],root=0; //某些情况求出的并不是重心,但要完全求出正确的重心很可能要花费更多的时间 
    57         getroot(edge[i].to,k);
    58         work(root);
    59     }
    60     return;
    61 }
    62 inline void reset(){
    63     memset(last,0,sizeof(last));
    64     memset(vis,0,sizeof(vis));
    65     ans=edge_tot=0;
    66 }
    67 void solve(){
    68     int t1,t2,t3;
    69     if(!n) exit(0);
    70     for(int i=1;i<n;i++){scanf("%d%d%d",&t1,&t2,&t3);add_edge(t1,t2,t3);add_edge(t2,t1,t3);}
    71     root=0,tot=n;
    72     getroot(1,0);
    73     work(root);
    74     printf("%d
    ",ans);
    75     reset();
    76     return; 
    77 }
    78 int main(){
    79     f[0]=oo;
    80     while(scanf("%d%d",&n,&maxd)) solve();
    81     return 0;
    82 }
  • 相关阅读:
    简单排序
    vue router在history模式下 如何部署在tomcat上
    概率论复习纲要
    MyBatis学习笔记(持续更新 2021/01/06- 2021/01/10)
    JavaWeb学习笔记(持续编辑2021/1/5-)
    2021/01/10周学习总结
    将WiFi搞得可以认证石铁大校园网(小米3路由器)
    对老师的建议
    自我感觉加分项
    github、gitee冲突配置ssh key
  • 原文地址:https://www.cnblogs.com/mycups/p/8527919.html
Copyright © 2020-2023  润新知