• POJ 1987 Distance Statistics 树分治


    Distance Statistics
     
     

    Description

     

    Frustrated at the number of distance queries required to find a reasonable route for his cow marathon, FJ decides to ask queries from which he can learn more information. Specifically, he supplies an integer K (1 <= K <= 1,000,000,000) and wants to know how many pairs of farms lie at a distance at most K from each other (distance is measured in terms of the length of road required to travel from one farm to another). Please only count pairs of distinct farms (i.e. do not count pairs such as (farm #5, farm #5) in your answer). 
     

    Input

     

    * Lines 1 ..M+1: Same input format as in "Navigation Nightmare" 

    * Line M+2: A single integer, K. 
     

    Output

     

    * Line 1: The number of pairs of farms that are at a distance of at most K from each-other. 
     

    Sample Input

     

    7 6
    1 6 13 E
    6 3 9 E
    3 5 7 S
    4 1 3 N
    2 4 20 W
    4 7 2 S
    10

    Sample Output

     

    5

    Hint

    There are 5 roads with length smaller or equal than 10, namely 1-4 (3), 4-7 (2), 1-7 (5), 3-5 (7) and 3-6 (9). 
     

    题解:

      POJ 1741 

      http://www.cnblogs.com/zxhl/p/5692688.html

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const int N = 4e4+20, M = 1e2+10, mod = 1e9+7, inf = 1e9+1000;
    typedef long long ll;
    
    int ans, n,m,root , t = 1,K,siz[N],head[N],f[N],deep[N],d[N],allnode,vis[N];
    struct edg{int to,next,v,w;}e[N * 4];
    void add(int u,int v,int w) {e[t].to=v;e[t].v=w;e[t].next=head[u];head[u]=t++;}
    
    void getroot(int x,int fa) {
        siz[x] = 1;
        f[x] = 0;
        for(int i=head[x];i;i=e[i].next) {
            int to = e[i].to;
            if(to == fa || vis[to]) continue;
            getroot(to,x);
            siz[x] += siz[to];
            f[x] = max(f[x] , siz[to]);
        }
        f[x] = max(f[x] , allnode - siz[x]);
        if(f[x] < f[root]) root = x;
    }
    void getdeep(int x,int fa) {
        if(d[x] <= K) deep[++deep[0]]=d[x];
        for(int i=head[x];i;i=e[i].next) {
            int to = e[i].to;
            if(to == fa || vis[to]) continue;
            d[to] = d[x] + e[i].v;
            getdeep(to,x);
        }
    }
    int cal(int x,int now) {
        d[x]=now;deep[0] = 0;
        getdeep(x,0);
        sort(deep+1,deep+deep[0]+1);
        int all = 0;
        for(int l=1,r=deep[0];l<r;) {
            if(deep[l]+deep[r] <= K) {all+=r-l;l++;}
            else r--;
        }
        return all;
    }
    void work(int x) {
        ans+=cal(x,0);
        vis[x] = 1;
        for(int i=head[x];i;i=e[i].next) {
            int to = e[i].to;
            if(vis[to]) continue;
            ans-=cal(to,e[i].v);
            allnode = siz[to];
            root = 0;
            getroot(to,root);
            work(root);
        }
    }
    void init()
    {
        memset(head,0,sizeof(head));
        t = 1;
        ans = root = 0;
        memset(vis,0,sizeof(vis));
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)) {
            init();
            for(int i=1;i<n;i++) {
                int a,b,c;char ch[2];
                scanf("%d%d%d%s",&a,&b,&c,ch);
                add(a,b,c) , add(b,a,c);
            }
            scanf("%d",&K);
            allnode=n;f[0]=inf;
            getroot(1,0);
            work(root);
            printf("%d
    ",ans);
        }
    
    }

     

  • 相关阅读:
    游戏性能保障体系
    一个ServiceHost寄宿多个服务
    EntLib PIAB 自定义CallHandler的一个BUG
    从MDK分散加载文件学习STM32启动流程
    .net 2.04.6下载
    QQ输入法使用「智能英文」模式(CTRL+SHIFT+E),快速输入英文单词
    QQ拼音输入法自定义短语(①②③≥≈÷★)
    指法输入中文打字俱乐部(TypingClub)是一款可以让用户从 0 开始练习打字的在线服务
    文件批量改名工具(RefilesName V2.0.exe)需要用安装「32位的VC++ 2005」
    博客园的「网摘」crx浏览器插件不错,支持键入多个标签
  • 原文地址:https://www.cnblogs.com/zxhl/p/5692947.html
Copyright © 2020-2023  润新知