zoukankan      html  css  js  c++  java
  • poj1741 树上的分治

    题意是说给了n个点的树n<=10000,问有多少个点对例如(a,b)他们的之间的距离小于等于k 采用树的分治做

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <algorithm>
    #include <vector>
    using namespace std;
    const int maxn=20005;
    int H[maxn],nx[maxn*2],to[maxn*2],numofE,dist[maxn*2];
    void add(int u, int v, int d)
    {
        numofE++;
        dist[numofE]=d,
        to[numofE]=v,
        nx[numofE]=H[u],
        H[u]=numofE;
    }
    void init(int N)
    {
       numofE=0;
       memset(H,0,sizeof(H));
    }
    int ans;
    bool center[maxn];
    int subnum[maxn];
    int Q[maxn+10],fa[maxn];
    int searchroot(int cur)
    {
         int rear=0,root=cur;
         Q[rear++]=cur;fa[cur]=0;
         for(int i=0; i<rear; i++){
             int x= Q[i];
             for(int j=H[x]; j; j=nx[j])
                if(to[j]!=fa[x]&& center[ to[j] ]==false)
                  Q[rear++]=to[j],fa[to[j]]=x;
         }
         int MIN=100000000;
         for(int i=rear-1; i>=0; i--){
    
             int x=Q[i];
    subnum[x]=1;
    int MA=0;
             for(int j=H[x]; j ; j=nx[j])
                if(to[j]!=fa[x]&&center[ to[j] ]==false)
                    MA=max(MA,subnum[to[j]]),subnum[x]+=subnum[to[j]];
             MA=max(MA,rear-subnum[ x ]);
             if(MIN>MA)MIN=MA,root=x;
         }
         return root;
    }
    int P[maxn];
    int N,K;
    int count_pair(int s, int t){
       int ge=0,R=t;
       for(int i=s; i<t; i++)
        {
            while(R>s&&P[R-1]+P[i]>K)R--;
            ge+=R-s-(R>i?1:0);
        }
       return ge/2;
    }
    void updateedg(int s, int cur, int d)
    {
         int rear=0;
         Q[rear++]=cur; fa[cur]=0;P[s]=d;
         for(int i=0; i<rear; i++)
         {
             int x=Q[i];
             for(int j=H[x]; j; j=nx[j])
             {
                 int tto=to[j];
                 if(center[tto]||tto==fa[x])continue;
                 P[s+rear]=P[s+i]+dist[j],Q[rear++]=tto,fa[tto]=x;
             }
         }
         sort(P+s,P+s+rear);
    }
    int dfs(int s,int cur,int d)
    {
        int root,tot=1;
        root=searchroot(cur);
        center[root]=true;
        for(int i=H[root]; i ; i=nx[i])
        {
             int tto=to[i];
             if(center[tto])continue;
             int n=dfs(s+tot,tto,dist[i]);
             ans-=count_pair(s+tot,s+tot+n);
             tot+=n;
        }
        P[s]=0;
        sort(P+s,P+s+tot);
        ans+=count_pair(s,s+tot);
        center[root]=false;
        updateedg(s,cur,d);
        return tot;
    }
    
    int main()
    {
        memset(center,false,sizeof(center));
        while(scanf("%d%d",&N,&K)==2)
            {
                 if(!N&&!K)break;
                  ans=0;
                  init(N);
                  for(int i=1; i<N; i++){
                    int a,b,d;
                    scanf("%d%d%d",&a,&b,&d);
                    add(a,b,d);add(b,a,d);
                  }
                  dfs(0,1,0);
                  printf("%d
    ",ans);
            }
        return 0;
    }
    View Code
  • 相关阅读:
    linux开机启动服务配置
    流媒体服务器配置安装SRS及nginx+rtmp
    WEBRTC配置安装
    linux操作20200825
    转载流媒体服务器相关收藏
    RabbitMQ中间件使用
    如何查找删除指定进程
    硬件接口,串行比并行快的原因
    JavaBean+jsp开发模式 --结合form表单 实例
    session会话
  • 原文地址:https://www.cnblogs.com/Opaser/p/4856012.html
Copyright © 2011-2022 走看看