1 条题解
-
0
题目概述
有 个城市, 条双向道路,形成一个连通图。每个居民要访问其他所有居民一次,总共需要 次会面。
如果封锁一个城市,那么这个城市无法被访问,也无法通过该城市访问其他城市。我们需要计算封锁每个城市时,无法进行的会面次数。
问题分析
关键观察
- 图的连通性:原图是连通的,但封锁一个城市后图可能变得不连通
- 会面计数:两个居民能会面当且仅当他们在封锁后的图中连通
- 问题转化:对于每个城市 ,计算封锁它后,所有不连通的点对数量
数学形式化
设封锁城市 后,图分裂成若干个连通分量,大小分别为 。
那么无法进行的会面次数为:
因为原本有 次会面,封锁后只剩下各个连通分量内部的会面。
算法思路
使用割点理论
这个问题本质上是在求:对于每个点,删除它后图分裂成的各个连通分量的大小。
这正好是Tarjan算法求割点时能够计算的信息。
Tarjan算法回顾
在DFS遍历图时,维护:
dfn[u]:DFS序(时间戳)low[u]:通过回边能回到的最早祖先
点 是割点当且仅当:
- 如果 是根节点,且有多于1个子树
- 如果 不是根节点,且存在子节点 满足
low[v] >= dfn[u]
计算答案
在Tarjan算法过程中,对于每个点 :
如果 不是割点
封锁 只会影响直接经过 的会面:
- 无法与其他 个点会面
- 其他 个点无法与 会面
- 总共 次会面无法进行
如果 是割点
封锁 后,图会分裂成多个连通分量。
设删除 后产生的连通分量大小为 ,那么无法进行的会面次数为:
在Tarjan过程中,当我们发现 满足
low[v] >= dfn[u]时,以 为根的子树就是一个连通分量,大小为siz[v]。
算法详解
核心代码解析
数据结构
int dfn[N], low[N], sn; // DFS序相关 long long ans[N], siz[N]; // 答案和子树大小 int cut[N]; // 标记是否为割点Tarjan算法
void tarjan(int u, int last) { dfn[u] = low[u] = ++sn, siz[u] = 1; int son = 0, v, sum = 0; for (int i = head[u]; i; i = e[i].ne) { if (i == (last ^ 1)) continue; // 避免重复访问父边 v = e[i].v; if (!dfn[v]) { tarjan(v, i); siz[u] += siz[v]; // 累加子树大小 low[u] = min(low[u], low[v]); if (low[v] >= dfn[u]) { // 发现割点条件 if (u != root || ++son > 1) cut[u] = 1; ans[u] += siz[v] * (n - siz[v]); // 累加这个分量的贡献 sum += siz[v]; // 记录已处理的子树大小 } } else { low[u] = min(low[u], dfn[v]); } } // 最终处理答案 if (!cut[u]) { ans[u] = 2LL * (n - 1); // 非割点情况 } else { // 割点情况:还要加上剩余部分(包含父节点那边的分量) ans[u] += 1LL * (n - sum - 1) * (sum + 1) + (n - 1); } }答案计算原理
对于割点 :
ans[u] += siz[v] * (n - siz[v]):分量 与图中其他点的点对(n - sum - 1) * (sum + 1):父节点那边的分量与已处理分量的点对(n - 1): 本身与其他点的会面
样例解析
样例输入
5 5 1 2 2 3 1 3 3 4 4 5图结构:三角形1-2-3,加上链3-4-5。
计算结果
- 城市1,2,5:不是割点,答案
- 城市3:割点,删除后分成 {1,2} 和 {4,5},答案
- 城市4:割点,删除后分成 {1,2,3} 和 {5},答案
输出:
8 8 16 14 8
复杂度分析
- 时间复杂度:
- Tarjan算法每个点和边只访问一次
- 空间复杂度:
- 存储图和算法所需数组
总结
这道题的关键在于:
- 问题转化:将会面次数问题转化为图连通性问题
- 割点理论:利用Tarjan算法识别割点并计算删除后的连通分量
- 组合计数:通过连通分量大小计算受影响的点对数量
- 高效算法:在DFS过程中同时完成所有计算,达到线性复杂度
这种"图论+组合计数"的问题在竞赛中很常见,Tarjan算法是解决这类问题的有力工具。
- 1
信息
- ID
- 4858
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者