[ABC213G] Connectivity 2
题目大意
给你 \(n\) 点 \(m\) 边的图,问有多少种删边方法使得 1 与 k 仍然联通。
\(1\le n\le 17, m\le \dfrac{n(n-1)}{2}\)
解题思路
看到 \(n\le 17\) ,显然是一道状压dp,但是 \(m\le 136\),显然不能枚举边。
于是枚举点,显然的,有:连通图的数量=所有图的数量-非连通图的数量。
所以令 \(f_i,g_i\) 分别为只选 \(i\) 集合内的点和点之间的边的 连通图的数量与所有图的数量。
又所有图的数量为边之间随机连的个数,有 \(g_i=2^{\sum\limits_{e_j=\{u,v\}}{u\in i\land v\in i}}\)
如何计算 \(f_i\) 呢,根据上面的柿子,现在需要计算非联通图的数量,我们将图分为两部分,两部分之间不连边,就是一个非连通图。
但是可能重复计数,所以钦定一个点一定 \(v\) 在某一部分里,所以有非连通图的数量 \(h_i=\sum\limits_{j\subset all\land i\in j}{f_jg_{all\setminus j}}\)
所以有 \(f_i=g_i-h_i\),状压即可。
怎么计算答案呢?显然是包含 \(1,k\) 的连通图加上其他的点构成的图就行了。
所以有 \(ans_i=\sum\limits_{j\subset i\land 1\in j\land k\in j}f_jg_{i\setminus j}\)
时间复杂度:因为计算 \(g\) 的复杂度为 \(O(m2^n)\),枚举子集的子集的复杂度为 \(O(3^n)\),计算答案复杂度为 \(O(n2^n)\) 所以总时间复杂度为 \(O(3^n+(n+m)2^n)\)
细节
- 注意计算答案的时候 \(1\) 和 \(k\) 要在连通图中。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
const int N = 17, M = 200, p = 998244353;
int u[M], v[M], g[1 << N], f[1 << N], n, m;
ll qpow(ll a, ll b)
{
if(b == 0) return 1;
if(b == 1) return a;
return (b & 1) ? a * qpow(a * a % p, b >> 1) % p : qpow(a * a % p, b >> 1);
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> m;
for(int i = 1; i <= m; i ++)
cin >> u[i] >> v[i];
int _2n = 1 << n;
for(int i = 0; i < _2n; i ++)
{
for(int j = 1; j <= m; j ++)
if(((1 << u[j] - 1) & i) && ((1 << v[j] - 1) & i))
g[i] ++;
g[i] = qpow(2, g[i]);
}
for(int i = 0; i < _2n; i ++)
{
f[i] = g[i];
int k = i & (-i);
for(int j = (i - 1) & i; j; j = (j - 1) & i)
if(j & k)
(f[i] -= f[j] * g[i ^ j]) %= p;
}
for(int i = 1; i < n; i ++)
{
int ans = 0;
for(int j = 1; j < _2n; j += 2)
if(j & (1 << i))
(ans += f[j] * g[(_2n - 1) ^ j]) %= p;
cout << (ans + p) % p << "\n";
}
return 0;
}
作者:adam01
出处:https://www.cnblogs.com/adam01/p/17681390.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通