当前位置: 首页 > news >正文

题解:AtCoder AT_awc0081_c Spread of Rumors

【题目来源】

AtCoder:C - Spread of Rumors

【题目描述】

There are \(N\) people, numbered from \(1\) to \(N\). There are a total of \(M\) one-way communication channels among the people. The \(i\)-th communication channel allows person \(U_i\) to send a message to person \(V_i\).

Initially (at the start of day \(0\)), only person \(S\) knows a certain rumor. The spread of the rumor proceeds day by day according to the following rules:

  • Each person who knows the rumor at the start of day \(d\) (\(d = 0, 1, 2, \ldots\)) simultaneously sends the rumor through all communication channels originating from that person. The sent rumors arrive at the start of day \(d+1\), and the recipients become aware of the rumor from that point onward.
  • A person who newly learns the rumor at the start of day \(d+1\) can only actually send the rumor from day \(d+1\) onward.
  • Once a person learns the rumor, they remain aware of it permanently.

Find the day \(d\) when all people first become aware of the rumor. That is, output the smallest \(d\) such that at the start of day \(d\), all people know the rumor for the first time. If all people already know the rumor at the start of day \(0\) (such as when \(N = 1\)), output \(0\). If the rumor cannot reach all people no matter how many days pass, output \(-1\).

\(N\) 个人,编号从 \(1\)\(N\)。这些人之间共有 \(M\) 条单向通信信道。第 \(i\) 条通信信道允许人物 \(U_i\) 向人物 \(V_i\) 发送消息。

初始时(在第 \(0\) 天开始时),只有人物 \(S\) 知道某个谣言。谣言的传播按以下规则逐天进行:

  • 在第 \(d\) 天开始时(\(d = 0, 1, 2, \ldots\))知道谣言的每个人,会同时通过所有从他们出发的通信信道发送谣言。发送的谣言在第 \(d+1\) 天开始时到达,接收者从那时起知道谣言。
  • 在第 \(d+1\) 天开始时新学到谣言的人,只能从第 \(d+1\) 天开始实际发送谣言。
  • 一旦一个人知道谣言,他们将永久保持知情。

求所有人首次都知道谣言的日子 \(d\)。也就是说,输出最小的 \(d\),使得在第 \(d\) 天开始时,所有人第一次都知道谣言。如果所有人已经在第 \(0\) 天开始时就知道谣言(例如 \(N = 1\) 的情况),输出 \(0\)。如果无论经过多少天,谣言都无法到达所有人,输出 \(-1\)

【输入】

\(N\) \(M\) \(S\)
\(U_1\) \(V_1\)
\(U_2\) \(V_2\)
\(\vdots\)
\(U_M\) \(V_M\)

  • The first line contains \(N\) representing the number of people, \(M\) representing the number of communication channels, and \(S\) representing the number of the person who initially knows the rumor, separated by spaces.
  • Lines \(2\) through \(M + 1\) contain the communication channel information.
  • The \((1 + i)\)-th line contains \(U_i\) and \(V_i\), separated by spaces, indicating that the \(i\)-th communication channel goes from person \(U_i\) to person \(V_i\).

【输出】

Output in a single line the earliest day \(d\) when all people become aware of the rumor. However, if the rumor cannot spread to all people, output \(-1\).

【输入样例】

4 4 1
1 2
1 3
2 4
3 4

【输出样例】

2

【核心思想】

  1. 问题分析:给定 \(N\) 个人和 \(M\) 条单向通信信道,从第 \(S\) 个人开始传播谣言,每天谣言会沿着信道传播一层。求所有人都知道谣言的最小天数 \(d\)。这是一个BFS求最短路的最远距离问题,关键在于谣言传播的时间等于从起点到最远节点的最短路径长度。

  2. 算法选择

    • BFS(广度优先搜索):按层遍历图,计算从起点 \(S\) 到每个节点的最短距离
    • 距离数组 dist:记录从起点到每个节点的最短距离,\(-1\) 表示未访问
    • 最大距离统计:遍历所有节点,取最大距离作为答案
  3. 关键步骤

    • 建图:读取 \(N\)(人数)、\(M\)(信道数)、\(S\)(起点),使用邻接表存储有向图
    • BFS计算距离:从起点 \(S\) 开始BFS,计算 dist[i] 表示第 \(i\) 个人知道谣言的最小天数
    • 检查可达性:遍历所有节点,若存在 dist[i] == -1,说明有人无法知道谣言,输出 \(-1\)
    • 统计答案:取所有 dist[i] 的最大值,即为所有人都知道谣言的最小天数
  4. 时间/空间复杂度

    • 时间复杂度:\(O(N + M)\),BFS遍历所有节点和边一次
    • 空间复杂度:\(O(N + M)\),邻接表和距离数组
  5. BFS求最远距离的核心思想

    • 层序传播:BFS按层扩展,第 \(k\) 层节点距离起点为 \(k\),对应谣言传播 \(k\)
    • 第一次访问即最短:由于边权相同(每天传播一层),第一次访问即为最短时间
    • 最大距离决定答案:谣言传播到所有人需要的时间等于从起点到最远节点的距离
    • 适用于信息传播、谣言扩散、到达所有节点的最短时间类问题

【算法标签】

BFS-一维

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 400005, M = 200005;
int n, m, s, ans = -1;  // n: 节点数,m: 边数,s: 起点,ans: 最大距离
int h[N], e[M], ne[M], idx;  // 邻接表
int dist[N];  // 距离数组void add(int a, int b)  // 添加有向边
{e[idx] = b, ne[idx] = h[a], h[a] = idx++;  // 将边添加到邻接表
}void bfs()  // 广度优先搜索
{memset(dist, -1, sizeof(dist));  // 初始化距离为-1queue<int> q;  // 创建队列q.push(s);  // 起点入队dist[s] = 0;  // 起点距离为0while (!q.empty())  // 当队列不为空{int u = q.front();  // 取队首q.pop();  // 出队for (int i = h[u]; i != -1; i = ne[i])  // 遍历邻居{int v = e[i];  // 邻居节点if (dist[v] == -1)  // 如果未访问{dist[v] = dist[u] + 1;  // 更新距离q.push(v);  // 入队}}}
}
int main()
{cin >> n >> m >> s;  // 输入节点数、边数、起点memset(h, -1, sizeof(h));  // 初始化邻接表while (m--)  // 处理每条边{int u, v;cin >> u >> v;  // 输入有向边add(u, v);  // 添加边}bfs();  // 执行广度优先搜索for (int i = 1; i <= n; i++)  // 遍历所有节点{if (dist[i] == -1)  // 如果有节点不可达{cout << -1 << endl;  // 输出-1return 0;}ans = max(ans, dist[i]);  // 更新最大距离}cout << ans << endl;  // 输出最大距离return 0;
}

【运行结果】

4 4 1
1 2
1 3
2 4
3 4
2
http://www.zskr.cn/news/1523194.html

相关文章:

  • 天地图、OpenStreetMap、ArcGIS Online,Web地图瓦片服务(WMTS/TMS/XYZ)到底怎么选?一个前端开发者的实战踩坑笔记
  • 题解:学而思编程 均富卡
  • 2026湖州厂区电能质量测试评估放心机构 TOP + 实地测评 + 详细地址电话 - 中检检测集团
  • 2026昌吉地区本地人常去的 5 家土壤检测农田污染场地检测第三方机构实体店实地测评汇总 - 科信检测
  • 5分钟掌握猫抓Cat-Catch:浏览器资源嗅探神器的完整使用指南
  • 从/dev/fb0到DRM:一个嵌入式工程师的Linux显示框架踩坑与选型指南
  • 天花板!2026 实验室装修公司推荐 5大企业实力透视+ 全场景选型秘籍 - 速递信息
  • 题解:学而思编程 奶牛杂技团
  • 2026吉林本地水质检测饮用水检测哪家强?TOP 正规机构榜单 + 联系方式 - 中安检测集团
  • 2026贵阳厂区电能质量测试评估放心机构 TOP + 实地测评 + 详细地址电话 - 中检检测集团
  • AMD Ryzen处理器调校终极指南:5步解锁隐藏性能的免费工具
  • 2026喀什本地水质检测饮用水检测哪家强?TOP 正规机构榜单 + 联系方式 - 中安检测集团
  • 2026潜江市迪奥+古驰+普拉达包包专业回收,2026甄选回收店铺排行榜推荐 - 奢金汇
  • 2026日喀则市爱马仕+香奈儿+路易威登LV包包专业回收,2026甄选回收店铺排行榜推荐 - 奢金汇
  • 题解:AtCoder AT_awc0082_d Corridor Doors and Hit Points
  • 数据科学转行真实路径图:3条可落地的实战路线
  • 为你的STM32小屏幕找个GUI:在1.8寸TFT上移植LVGL或U8g2的实战记录
  • 2026揭阳厂区电能质量测试评估放心机构 TOP + 实地测评 + 详细地址电话 - 中检检测集团
  • 飞腾D2000+银河麒麟V10开发笔记:网络编程时获取本机IP的几种方法对比
  • 视频转PPT:如何从3小时会议录像中提取出完美演示文稿
  • 终极QQ音乐解密指南:3分钟解锁你的加密音乐库
  • dendrogram如何提升销售预测准确率:产品相似性建模实战
  • skill 知识
  • 用GPT-Builder打造Plotly地理可视化AI助手
  • 基于PLC控制的汽车铰链自动压装机虚拟样机设计3124(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 企业级SSD批量供货与品质一致性FAQ
  • DOTA数据集标注避坑指南:HBB和OBB选错了,模型效果差一半
  • 2026巴音本地水质检测饮用水检测哪家强?TOP 正规机构榜单 + 联系方式 - 中安检测集团
  • 2026汉中本地水质检测饮用水检测哪家强?TOP 正规机构榜单 + 联系方式 - 中安检测集团
  • Windows Cleaner:开源系统清理与优化工具技术解析