zoukankan      html  css  js  c++  java
  • 点分治

    1.洛谷 点分治1

    //Twenty
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    const int maxn=10000+299;
    const int maxm=100+5;
    const int maxk=10000000+29;
    using namespace std;
    int bo[maxk],fir[maxn],nxt[maxn*2],to[maxn*2],val[maxn*2],vis[maxn],root,ecnt;
    int n,m,sum,dis[maxn],sz[maxn],qs[maxm],mx[maxn],ans[maxm],top[maxn],que[maxn];
    void add(int u,int v,int w){
        nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
        nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
    }
    void dfs(int x,int fa){
        for(int i=1;i<=m;i++){
             if(qs[i]-dis[x]>=0&&bo[qs[i]-dis[x]]==top[x])  ans[i]=1;
            }
        for(int i=fir[x];i;i=nxt[i]){
            if(x==top[x]&&que[0]){
               for(int j=1;j<=que[0];j++)
                bo[dis[que[j]]]=x;
               que[0]=0;
            }
            int v=to[i];
            if(v==fa||vis[v]) continue;
            dis[v]=dis[x]+val[i];
            top[v]=top[x];
            que[++que[0]]=v;//避免同一子树中的误判,压入队列 
            dfs(v,x);
        }
    }    
    void get_root(int x,int fa){
        sz[x]=1; mx[x]=1;
        for(int i=fir[x];i;i=nxt[i]){
            int v=to[i];
            if(vis[v]||v==fa) continue;
            get_root(v,x);
            sz[x]+=sz[v];
            mx[x]=max(mx[x],sz[v]); 
        }
        mx[x]=max(mx[x],n-sz[x]);
        if(mx[x]<mx[root]) root=x;
    }
    void work(int x){
        dis[x]=0; 
        bo[0]=x;
        top[x]=x;
        vis[x]=1;
        dfs(x,0);
        for(int i=fir[x];i;i=nxt[i]){
            int v=to[i];
            if(vis[v]) continue;
            root=0;
            sum=sz[v];
            get_root(v,x);
            work(root);
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m); 
        sum=n; mx[0]=n+299;
        for(int i=1;i<n;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
        }
        for(int i=1;i<=m;i++)
        scanf("%d",&qs[i]);
        get_root(1,0);
        work(root);
        for(int i=1;i<=m;i++){
            if(ans[i]) printf("AYE
    ");
            else printf("NAY
    ");
        }
        return 0;
    }
    点分治 1

    2.洛谷 聪聪可可

    //Twenty
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    const int maxn=20000+299;
    int ecnt,fir[maxn],nxt[maxn*2],to[maxn*2],val[maxn*2],vis[maxn],root,n; 
    int ans,f[5],sz[maxn],mx[maxn],sum,dis[maxn];
    using namespace std;
    int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
    void add(int u,int v,int w){
        nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w%3;
        nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w%3;
    }
    void dfs(int x,int fa){
        f[dis[x]]++;
        for(int i=fir[x];i;i=nxt[i]){
            int v=to[i];
            if(vis[v]||v==fa) continue;
            dis[v]=(dis[x]+val[i])%3;
            dfs(v,x);
        }
    }
    int cul(int x,int d){
        dis[x]=d; 
        f[0]=f[1]=f[2]=0; 
        dfs(x,0);
        return f[0]*f[0]+f[1]*f[2]*2;
    }
    void get_root(int x,int fa){
        sz[x]=1; mx[x]=0;
        for(int i=fir[x];i;i=nxt[i]){
            int v=to[i];
            if(v==fa||vis[v]) continue;
            get_root(v,x);
            sz[x]+=sz[v]; mx[x]=max(mx[x],sz[v]);
        }
        mx[x]=max(mx[x],sum-sz[x]);
        if(mx[x]<mx[root]) root=x;
    }
    void work(int x){
        ans+=cul(x,0); vis[x]=1;
        for(int i=fir[x];i;i=nxt[i]){
            int v=to[i];
            if(vis[v]) continue;
            ans-=cul(v,val[i]);
            sum=sz[v];
            root=0; get_root(v,x);
            work(root);
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
        }
        mx[0]=n+1;
        sum=n;
        get_root(1,0);
        work(root);
        int t=gcd(n*n,ans);
        printf("%d/%d
    ",ans/t,n*n/t);
        return 0;
    }
    聪聪可可

     

  • 相关阅读:
    Ruby小白入门笔记之<个人记录档>
    Windows 10下怎么远程连接 Ubuntu 16.0.4(小白级教程)
    Ruby小白入门笔记之<Rails项目目录结构>
    GitHub 上传文件
    机器学习:项目流程及方法(以 kaggle 实例解释)
    数据科学:待学习的内容
    机器学习:项目流程
    数据科学:numpy.where() 的用法
    数据科学:Pandas 和 Series 的 describe() 方法
    Kaggle 比赛项目总结(项目流程)
  • 原文地址:https://www.cnblogs.com/Achenchen/p/7475196.html
Copyright © 2011-2022 走看看