zoukankan      html  css  js  c++  java
  • HDU4607 Park Visit(解法二)

    问题链接HDU4607 Park Visit

    题意简述莱克尔和她的朋友到公园玩,公园很大也很漂亮。公园包含n个景点通过n-1条边相连。克莱尔太累了,所以不能去参观所有点景点。经过深思熟虑,她决定只访问其中的k个景点。她拿出地图发现所有景点的入口都很特殊。所以她想选择一个入口,并找到一条最短的路来参观k个景点。假设景点之间的距离为1。

    输入数据:先输入测试用例数t,每个测试用例数据包括N和M,N为结点数,M为需要查询的上述的k(参观M个景点)

    输出数据:对于各个M,输出需要走的距离。

    问题分析:n个结点n-1条边构成无向无环树。该问题就是求树直径,树直径即树上最长路径。假设树直径包含m个结点(直径为m-1),若k<=m,则答案为k-1,否则答案为m + (k-m-1)*2。

    程序说明与同题的另外一种解法不同,这个程序先随意找出一个结点(程序中是结点1),用函数dfs(),求出1结点到其他各个结点的距离,dist[i]中存放1结点到i结点的距离,从中选出距离1结点最远的结点(程序中放在变量start中)。然后,再以结点start作为起点,函数dfs(),求出结点start到其他各个结点的距离,从中选出距离start结点最远的结点(程序中放在变量target中),那么从start到target的距离就是树直径。

    相比较而言,这个程序速度上会稍微快一些。参见:HDU4607 Park Visit


    AC的C++语言程序如下:

    /* HDU4607 Park Visit */
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    
    using namespace std;
    
    const int MAXN = 100000;
    vector<int>tree[MAXN+1];
    int maxlen, dist[MAXN+1];
    
    void dfs(int now, int last, int d[])
    {
        int u, size;
        size = tree[now].size();
        for(int i=0; i<size; i++)
            if ((u = tree[now][i]) != last) {
                d[u] = d[now] + 1;
                dfs(u, now, d);
            }
    }
    
    int main(void)
    {
        int t, n, m, u, v, k;
    
        scanf("%d", &t);
        while(t--) {
            scanf("%d%d", &n, &m);
    
            for(int i=1; i<=n; i++)
                tree[i].clear();
    
            for(int i=1; i<n; i++) {
                scanf("%d%d", &u, &v);
                tree[u].push_back(v);
                tree[v].push_back(u);
            }
    
            dist[1] = 0;
            dfs(1, 0, dist);
    
            int start = 0;
            dist[start] = 0;
            for(int i=1; i<=n; i++)
                if(dist[i] > dist[start])
                    start = i;
    
            dist[start] = 0;
            dfs(start, 0, dist);
            int target = 0;
            for (int i=1; i<=n; i++)
                if(dist[i] > dist[target])
                    target = i;
            maxlen = dist[target];
    
            while(m--) {
                scanf("%d", &k);
                if(k <= maxlen)
                    printf("%d
    ", k-1);
                else
                    printf("%d
    ", maxlen + (k-maxlen-1)*2);
            }
        }
    
        return 0;
    }


  • 相关阅读:
    窥探算法之美妙——详细讲解寻找最长重复字符串的原理
    窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆
    窥探算法之美妙——统计整数二进制中1的个数
    第一次向开源项目贡献代码的历程
    编写高质量代码--改善python程序的建议(八)
    Mysql数据类型TINYINT(1)与BOOLEAN踩坑记
    Mysql Hash索引和B-Tree索引区别(Comparison of B-Tree and Hash Indexes)
    详解计算机中的Byte、bit、字、字长、字节
    什么是不忘初心
    最简单的JS实现json转csv
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564346.html
Copyright © 2011-2022 走看看