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

    Time Limit: 1 Sec  Memory Limit: 30 MB
    Submit: 13  Solved: 9
    [Submit][Status][Web Board]

    Description

    Give a tree with n vertices,each edge has a length(positive integer less than 1001). 
    Define dist(u,v)=The min distance between node u and v. 
    Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k. 
    Write a program that will count how many pairs which are valid for a given tree. 

    给定一个带权树N个结点(1<=N<=10000),定义dist(u,v)为u,v两个点间的最 
    短路径长度,路径长度定义为路径上所有边的权和。再给定一个K(1<=K<=10^9) 
    如果对于不同的两个结点a,b.如果满足dist(a,b)<=K,则称其为合法点对,求 
    有多少合法点对

    Input

    The input contains several test cases. 
    The first line of each test case contains two integers n, k. (n<=10000) 
    The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l. 
    The last test case is followed by two zeros. 

    Output

    For each test case output the answer on a single line. 

    Sample Input

    5 4
    1 2 3
    1 3 1
    1 4 2
    3 5 1
    0 0

    Sample Output

    8

    HINT

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;

    struct my{
        int next,v,w;
    };

    int read()
    {
        int p,data=0;
        char ch=0;
        while ((ch!='-') && ch<'0' || ch>'9') ch=getchar();
        if (ch=='-')
        {
            p=-1;
            ch=getchar();
        } else p=1;
        while (ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
        return data*p;
    }

    const int maxn=10000+10;

    my bian[maxn*2];
    int adj[maxn],fa,n,k,root=0,son[maxn],minn=(1<<30),dis[maxn*10],tot,sum;
    bool done[maxn];

    void myinsert(int u,int v,int w){
         bian[++fa].v=v;
         bian[fa].w=w;
         bian[fa].next=adj[u];
         adj[u]=fa;
    }

    void dfs(int x,int fa){
        int pp=0;
        son[x]=1;
        for (int i=adj[x];i;i=bian[i].next){
            int v=bian[i].v;
            if(v==fa||done[v]) continue;
            dfs(v,x);
            son[x]+=son[v];
            pp=max(pp,son[v]);
        }
        pp=max(pp,sum-son[x]);//ÁíÍâÒ»´ó¿ÅÊ÷
        if(pp<minn) {
                minn=pp,root=x;
        }
    }

    void dfs2(int x,int d,int fa){
         dis[++tot]=d;
         for (int i=adj[x];i;i=bian[i].next){
                int v=bian[i].v;
            if(!done[v]&&v!=fa){
                dfs2(v,d+bian[i].w,x);
            }
         }
    }

    int calc(int x,int d){
        tot=0;
        int ans=0;
        dfs2(x,d,0);
        sort(dis+1,dis+1+tot);
        int i=1,j=tot;
        for (;i<j;i++){
            while(dis[i]+dis[j]>k && i<j) j--;
            ans+=j-i;
        }
        return ans;
    }

    int work(int x){
        minn=(1<<30);
        dfs(x,0);
        done[root]=true;
        int ans=0;
        ans+=calc(root,0);
        for (int i=adj[root];i;i=bian[i].next){
                int v=bian[i].v;
            if(done[v]) continue;
            sum=son[v];
            ans-=calc(v,bian[i].w);
            ans+=work(v);
        }
        return ans;
    }

    int main(){
        int u,v,w;
        while(scanf("%d%d",&n,&k)&&k+n){
                memset(bian,0,sizeof(bian));
                memset(adj,0,sizeof(adj));
                memset(done,false,sizeof(done));
                fa=0;
        for (int i=1;i<n;i++){
            u=read();
            v=read();
            w=read();
            myinsert(u,v,w);
            myinsert(v,u,w);
           }
           sum=n;
           printf("%d ",work(1));
        }
    return 0;
    }

  • 相关阅读:
    欧拉公式
    isap的一些想法
    错误合集
    Hello World
    PAT (Advanced Level) Practice 1068 Find More Coins
    PAT (Advanced Level) 1087 All Roads Lead to Rome
    PAT (Advanced Level) 1075 PAT Judge
    PAT (Advanced Level) 1067 Sort with Swap(0, i)
    PAT (Advanced Level) 1017 Queueing at Bank
    PAT (Advanced Level) 1025 PAT Ranking
  • 原文地址:https://www.cnblogs.com/lmjer/p/9214403.html
Copyright © 2011-2022 走看看