2019E0_F 多多岛

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44024733/article/details/102752450

多多岛

题目

知识点:树,古典概率

多多群岛是一个群岛,由n个岛屿构成,不同的岛屿之间由桥梁连接,一共有n-1个桥梁,任意两个岛屿一定联通。从一座岛屿跨过一座桥梁到另一个岛屿的时间是1。

多多群岛在只有一座桥与其他岛屿相连的岛屿上设有餐厅,就餐时间时,游客会选择距离他最近的餐厅就餐。

假设就餐时间时,一个游客在每座岛屿的概率相等,那么请问他到达餐厅花费时间的期望是多少。

输入

第一行一个正整数n表示岛屿的个数(2≤n<105)

接下来n-1行,每行两个整数x,y,表示第x座岛和第y座岛之间有一座桥梁 (1≤x,y≤n)

输出

每组数据输出一行,保留4位小数

输入样例

2
1 2

输出样例

0.0000

思路

水题。

首先,你要认出来这是一个树。n个点,n-1条边,任意两点之间联通。

然后,你要认识到餐厅都是叶节点。在只有一座桥与其他岛屿相连的岛屿上设有餐厅。

那么这个问题就是每个点到最近叶节点最短路径长的和除以n。

把叶节点都放到队列里做一个bfs就ok了。

代码

#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;
typedef long long ll;
const int ms = 1e5 + 5;
vector<int> g[ms];
int d[ms], n, m;
bool vis[ms];
int main()
{
    int a, b;
    double t = 0;
    scanf("%d", &n);
    for (int i = 0; i < n - 1; ++i)
    {
        scanf("%d%d", &a, &b);
        g[a].push_back(b);
        g[b].push_back(a);
    }
    queue<int>q;
    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() == 1)
        {
            q.push(i);
            vis[i] = true;
            d[i] = 0;
        }
    }
    while (!q.empty())
    {
        int u = q.front(); q.pop();
        for (int i : g[u])
        {
            if (!vis[i])
            {
                d[i] = d[u] + 1;
                q.push(i);
                vis[i] = true;
            }
        }
    }
    double res = 0;
    for (int i = 1; i <= n; ++i)
    {
        res += d[i];
    }
    printf("%.4lf", res / n);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44024733/article/details/102752450