P3469 [POI2008]BLO-Blockade
题目大意
给定一张无向图,求每个点被封锁之后有多少个有序点对 ,满足 无法到达 。
解题思路
首先可以确定这题需要先求割点 这不是一看就知道吗???
然后对于图上一点 ,进行分类讨论:
-
若点 不为割点,则贡献为 ,因为除了这个点,其他 个点都不能到达这个点,而反过来又算一种方法。
-
若点 为割点,则会把原图分成 个部分:
-
。
-
个连通块。
然后设这些连通块的大小分别为 ,则总贡献为 。
对于连通块,此时又可以分成 个部分:
- 在 的子树中的 个联通块,只需在每次遇到 ,说明从 和 的子树出发,若不经过 ,则无法到达比 的 更小的节点,我们把 删掉时, 和 的子树就成为了一个连通块。
- 除了 和 的子树,其他的节点自成一个联通块(因为 是一个割点),只需在遇到 时,用变量 累加在 和 的子树中的连通块大小,那么这一部分的贡献为 (还要算上点 )。
此时,点 的贡献为 ,注意不需要 ,因为反过来的方案已经在上面计算过了。
-
AC CODE
#include<bits/stdc++.h>
#define _ 1000010
using namespace std;
struct Fastio
{
template <typename T>
inline Fastio operator>>(T &x)
{
x = 0;
char c = getchar();
while (c < '0' || c > '9')
c = getchar();
while (c >= '0' && c <= '9')
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return *this;
}
inline Fastio &operator<<(const char c)
{
putchar(c);
return *this;
}
inline Fastio &operator<<(const char *str)
{
int cur = 0;
while (str[cur])putchar(str[cur++]);
return *this;
}
template <typename T>
inline Fastio &operator<<(T x)
{
if (x == 0)
{
putchar('0');
return *this;
}
if (x < 0) putchar('-'), x = -x;
static int sta[45];
int top = 0;
while (x) sta[++top] = x % 10, x /= 10;
while (top) putchar(sta[top] + '0'), --top;
return *this;
}
} io;
int n, m, rt;
int tot, head[_], to[_ << 1], nxt[_ << 1];
int cnt_node, dfn[_], low[_];
int siz[_];
bool cut[_];
long long ans[_];
void add(int u, int v)
{
to[++tot] = v;
nxt[tot] = head[u];
head[u] = tot;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++cnt_node;
siz[u] = 1;
int flag = 0;
long long sum = 1;
for(int i = head[u]; i; i = nxt[i])
{
int v = to[i];
if(!dfn[v])
{
tarjan(v);
siz[u] += siz[v];
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u])
{
flag++;
sum += siz[v];
ans[u] += (long long)siz[v] * (n - siz[v]);
if(rt != u || flag > 1) cut[u] = 1;
}
}
else
low[u] = min(low[u], dfn[v]);
}
if(!cut[u]) ans[u] = (long long)2 * (n - 1);
else ans[u] += (long long)(n - sum) * sum + (n - 1);
}
signed main()
{
io >> n >> m;
for(int i = 1; i <= m; ++i)
{
int u, v;
io >> u >> v;
add(u, v);
add(v, u);
}
tarjan(rt = 1);
for(int i = 1; i <= n; ++i) printf("%lld\n", ans[i]);
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122144
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话