HDU4607 Park Visit(解法二)【废除!!!】

本文废除!!!

参见链接:HDU4607 Park Visit【DFS】



问题链接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\n", k-1);
            else
                printf("%d\n", maxlen + (k-maxlen-1)*2);
        }
    }

    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
简单车位管理程序 随着家庭购买汽车增加停车场车位紧张问题越来越突出。根据题目要求完成简单车位管理程序。 1.停车场有若干停车位(为说明问题,假定为3个),每个位置可以存放不同种类的的汽车,包括卡车Truck,客车Carriage和小轿车Car,但同一时刻一个位置只能存放0或1辆汽车。 2.管理系统模拟实际车辆停车的情况:新来车辆时如果有空位,按顺序为该车分配停车位; 车辆开走时,交纳相应停车费;统计各类车辆的数量。 3.定义描述停车场的类Park,其中有3个位置用于存放各类车辆。 4.定义基类Automobile,至少包括纯虚函数Pay用于显示车辆信息并交纳相应停车费。 5.定义派生类Truck,Carriage和Car,这些车辆除了拥有车牌号(字符串)、车辆已使用年数(整数)之外。 Truck还拥有载重量(浮点数,单位吨)属性,Carriage还拥有乘坐人数(整数,单位人)属性,Car还拥有排气量(浮点数,单位L)属性。具体实现上述纯虚函数Pay,显示每类车辆的相应信息,并给出计价提示,其中Truck收费2元/小时,Carriage收费1.5元/小时,Car收费1元/小时。 6.重载输入“>>”操作符,使得可以通过cin直接读入每类车辆的相应信息。 7.编写main函数,测试上述所要求的各种功能,即根据菜单命令为新来车辆分配停车位、开走车辆(输入车位编号)时付费、显示停车场中各类车辆的数量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值