zoukankan      html  css  js  c++  java
  • 题解:luoguP3806 【模板】点分治1(在线处理询问做法)

    题目描述

    给定一棵有n个点的树

    询问树上距离为k的点对是否存在。

    输入输出格式

    输入格式:

    n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径

    接下来m行每行询问一个K

    输出格式:

    对于每个K每行输出一个答案,存在输出“AYE”,否则输出”NAY”(不包含引号)

    输入输出样例

    输入样例#1: 
    2 1
    1 2 2
    2
    输出样例#1: 
    AYE

    说明

    对于30%的数据n<=100

    对于60%的数据n<=1000,m<=50

    对于100%的数据n<=10000,m<=100,c<=1000,K<=10000000

    题解:

    这题数据是真的水,交时以为要T,结果过了......

    直接套点分治板子,暴力在线处理每个询问,可以水过

    当处理完与i相关的每条路径后,直接两两组合,排序后直接分别求出大于等于k和小于等于k的路径数后,再将其相加并减去总的路径组合数,就是等于k的路径组合。处理每层的复杂度大致是O(n+nlogn)

    详情见代码:

    #include<bits/stdc++.h>
    #define MAXN 10005
    #define INF 1e9+7
    using namespace std;
    struct front_star{
        int to,next,w;
    }edge[MAXN<<1];
    int n,cnt=0,k,mx,root,ans=0,tot=1,siz,m;
    int head[MAXN],sz[MAXN],temp[MAXN],idx[MAXN];
    bool vis[MAXN];
    int maxn(int a,int b)
    {
        return a>b?a:b;
    }
    void addedge(int u,int v,int c)
    {
        cnt++;
        edge[cnt].to=v;
        edge[cnt].w=c;
        edge[cnt].next=head[u];
        head[u]=cnt;
    }
    void findroot(int u,int fa)
    {
        sz[u]=1;
        int msz=0;
        for(int i=head[u];~i;i=edge[i].next)
            {
                int v=edge[i].to;
                if(v!=fa&&!vis[v])
                   {
                      findroot(v,u); 
                      sz[u]+=sz[v];
                      msz=maxn(msz,sz[v]);     
                   }
            }
        msz=maxn(msz,siz-sz[u]);
        if(msz<mx)
           {
               mx=msz;
               root=u;
           }       
    }
    void init()
    {
        memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n-1;i++)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                addedge(a,b,c);
                addedge(b,a,c);
            }
    }
    void dist(int u,int fa)
    {
        for(int i=head[u];~i;i=edge[i].next)
            {
                int v=edge[i].to;
                if(!vis[v]&&v!=fa)
                   {
                       tot++;
                       idx[v]=tot;
                       temp[tot]=temp[idx[u]]+edge[i].w;
                       dist(v,u);
                   }
            }
    }
    int count_ans(int u,int val)
    {
        tot=1;
        idx[u]=1;
        temp[1]=val;
        dist(u,u);
        sort(temp+1,temp+1+tot);
        int L=1,R=tot,res1=0,res2=0,ret;
        while(L<=R)
              {
                   if(temp[L]+temp[R]<=k)
                      {
                          res1+=R-L;
                          L++;
                      }
                   else
                      R--;
              }
        L=1,R=tot;      
        while(L<=R)
              {
                   if(temp[L]+temp[R]>=k)
                      {
                           res2+=R-L;
                           R--;
                      }
                   else
                      L++;   
              } 
        ret=res1+res2-(tot*(tot-1))/2; 
        return ret;     
    }
    void divide(int u)
    {
        ans+=count_ans(u,0);
        vis[u]=true;
        for(int i=head[u];~i;i=edge[i].next)
            {
                int v=edge[i].to;
                if(!vis[v]&&!vis[v])
                   {
                        ans-=count_ans(v,edge[i].w);
                        siz=sz[v];
                        mx=INF;
                        findroot(v,u);
                        divide(root);  
                   }
            }
    }
    void query()
    {
        for(int i=1;i<=m;i++)
            {
                memset(vis,false,sizeof(vis));
                scanf("%d",&k);
                siz=n;
                mx=INF;
                ans=0;
                findroot(1,1);
                divide(root);
                if(ans==0)
                   printf("NAY
    ");
                else
                   printf("AYE
    ");   
            }
    }
    int main()
    {
        init();
        query();
        return 0;
    }
    View Code
  • 相关阅读:
    操作系统发展和分类
    操作系统绪论
    tomcat启动出现乱码解决方法
    Tomcat安装与卸载
    XML
    注解
    反射机制
    package和import机制
    访问控制权限
    MariaDB 配置远程访问权限
  • 原文地址:https://www.cnblogs.com/nanjolno/p/8994989.html
Copyright © 2011-2022 走看看