2021济南icpc K. Search For Mafuyu DFS签到题

奖牌榜 The 2021 ICPC Asia Jinan Regional Contest - Contest Session (pintia.cn)

签到题,手快的半小时内写完的可以获得铜牌 第210名的AC时间是32:50

第200名AC了两题,就是说有十个快男队只A了这题拿了铜牌

题目

Problem K. Search For Mafuyu

​ Input fifile: standard input

​ Output fifile: standard output

​ Time limit: 1 second

​ Memory limit: 512 megabytes

Mafuyu has hidden in Sekai, and Kanade is searching for her.

In Sekai, there is nothing but a lot of rooms. There are n rooms in Sekai, numbered from 1 to n. Besides,

n 1 pairs of rooms are directly connected by corridors, such that it is possible to move from one room

to any other one, using one or more corridors. In other words, rooms in Sekai form a tree.

Kanade is at room 1, and she knows that Mafuyu may hide in any room except room 1, with uniform

probability. In one second, Kanade can move to a room adjacent to the room she is currently in. Once

Kanade is in the same room with Mafuyu, she immediately fifinds her. What is the minimum expected

time for Kanade to fifind Mafuyu, if Kanade is taking the optimal strategy?

Input

The fifirst line contains an integer t (1 t 1 000) — the number of test cases.

The fifirst line in each test case contains an integer n (2 n 100) — the number of rooms.

Each of the following n 1 lines contains two integers a**i, b**i (1 a**i , b**i n) — the rooms connected by

the i-th corridor. It is guaranteed that it is possible to move from one room to any other one, using one

or more corridors.

Output

Output t real numbers. For each test case, output the minimum expected time. Your answer is considered

correct if the absolute or relative error is less than 109.

Example

standard input

4
2
1 2
5
1 2
2 3
3 4
1 5
7
1 2
1 3
2 4
2 5
3 6
3 7
10
1 2
2 3
3 4
1 5
5 6
6 7
1 8
8 9
9 10

standard output

1.0000000000
3.2500000000
5.3333333333
8.0000000000

简述题意

有n个房间,n-1个走道,使得所有房间都能走通。使得所有房间能构成一棵树。

从一个房间移动到另一个计一次时。

要求从1开始,搜索每个房间,计算搜索所有房间的平均用时。

sumTime = sum(vis)【首次访问用时】 sumTime / (n-1)

分析样例可得,无论以哪种路线走,最终的sumTime是一样的,此处不证

注意:这里要求一次走完,那么只要不是以单链表的形式出现,那有点是会重复访问到的。

此时我们需要记录第一次访问到的步数,但仍要借助该点继续访问其他点。

因此这里开两个数组,vis[]记录第一次的访问记录;pre[]记录整条路的访问情况

在这里插入图片描述

AC代码

本代码为赛后回宿舍重写的,部分写法与赛中有点不同,但思路一致

等有OJ平台加入该题后会进行重新测试

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n;  // 点数
int m;  // 边数
vector<list<int>>mp;
unordered_set<int>st;   // 记录现在已访问几个点
vector<int>pre; // 几步可达
vector<int>vis; // 第一次访问到的步数

void dfs(int from ,int to){
    pre[to] = pre[from]+1;
    // 全部访问完
    if (st.size() == n) {
        return ;
    }
    // 记录第一次访问的状况
    if (pre[to] != 0 && vis[to] == 0) {
        vis[to] = pre[to];
    }
    // 记录访问
    st.insert(to);

    for (auto &nex : mp[to]) {
        // 无向图,要进行一个判断,放置成环
        if (nex == from) {
            continue;
        }
        // 递归访问
        // to --> nex
        dfs(to, nex);
        // 回溯回来
        // nex --> to
        if (st.size() != n) {
            pre[to] = pre[nex]+1;
        }
    }
}

void solve()
{
    cin >> n;
    m = n-1;

    mp.clear();
    pre.clear();
    vis.clear();
    st.clear();

    mp.resize(n+1);
    pre.resize(n+1);
    vis.resize(n+1);

    for (int i = 0; i < m; i++) {
        int from, to;
        cin >> from >> to;
        // 无向图
        mp[from].push_back(to);
        mp[to].push_back(from);
    }

    // 便于计算,开始的前一步为-1步可达
    pre[0] = -1;
    dfs(0, 1);

    int sum = 0;
    for (int i = 1; i <= n; i++) {
        sum += vis[i];
    }

    printf("%.10lf\n", 1.0*sum/m);

    return ;
}

signed main (void)
{
    int T = 0;
    cin >> T;
    while (T--) {
        solve();
    }

    return 0;
}

铁牌选手的思路和代码,求大佬多多放过/(ㄒoㄒ)/~~


赛场状态太差了,两个半钟头才AC,一方面是读题能力不行,当天的状态也不好

这种明显的DFS题平常练习的时候明明可以很快写出来

而且一开始明知道是无向图,中间为了思考思路方便,先改成有向图来写,硬生生的WA了一发

北大官方讲解

给定一棵 n 个点的树,A 在 1 号点,B 的位置在 2-n 中均匀随机,A 不知道 B 的位置。现在 A 要去找 B,每秒可以走到一个相邻点,求在最优策略下的期望时间。
1 <= t <= 1 000
1 <= n <= 100


先假设走的路径是一个欧拉遍历。容易发现交换一个点的两棵子树答案不变。
有了上述结论之后,容易证明最优解确实是一个欧拉遍历,也就是不会半途返回。
按任意顺序 DFS 即可。时间复杂度 O(n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值