首页 > 其他分享 >[ABC213G] Connectivity 2 题解

[ABC213G] Connectivity 2 题解

时间:2024-10-15 22:00:39浏览次数:6  
标签:连通 子图 mathit 题解 复杂度 这部分 个数 Connectivity ABC213G

T3 [ABC213G] Connectivity 2

题意:给定一张无向图 \(G\),将其删去 \(0\) 条及以上的边构成一张新图,求对于所有点 \(k\in(1,n]\),使 \(k\) 与 \(1\) 连通的新图的个数。

比较套路的一道状压 DP。尽管刚开始思考毫无头绪。

Step 1.

令 \(f_S\) 表示点集为 \(S\) 的连通子图的个数,\(g_S\) 为点集为 \(S\) 的子图的个数,则答案 \(\mathit{ans}_i\) 可以表示为

\[\mathit{ans}_i=\sum_{\text{path}(1,i)\subseteq S}f_S\times g_{\complement S} \]

这部分复杂度是 \(O(2^nn)\) 的。

Step 2.

计算 \(g_S\)。这部分是简单的,求出满足两个端点 \(u,v\in S\) 的边 \((u,v)\) 的个数,记为 \(\mathit{cnt}\),则

\[g_S=2^{\mathit{cnt}} \]

这部分的复杂度是 \(O(2^nm)\)。

Step 3.

计算 \(f_S\)。正难则反,考虑容斥。$f_S=g_S-\text{点集为 \(S\) 的不连通子图的个数}$。

后面这部分又是一个很套路的计算方法:钦定一个点 \(u\in S\),把不连通子图分为两部分:包含 \(u\) 的连通块、不包含 \(u\) 的其他部分。则有

\[f_S=g_S-\sum_{v\in T\subset S}f_T\times g_{\complement T} \]

这部分需要枚举子集的子集,复杂度 \(O(3^n)\)。

综上,总复杂度为 \(O(3^n+2^nn+2^nm)\)。

坑点:

  1. 时刻注意状压的意义是从左到右还是从右到左。事实上,这道题与平常的状压不同,从左到右会方便很多。
  2. 在计算答案时所需要的 \(f_S\) 只需要包含 \(1\) 的点集,所以在计算 \(f_S\) 时只需要枚举 \(2^{n-1}\le S<2^n\) 的情况。所以我们上述的 “钦定一个点 \(u\in S\)” 也可直接钦定 \(1\)。
#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
#define int long long
using namespace std;

char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
int read(){
	int x=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x; 
}
template<typename T>
void write(T x,char sf='\n'){
	if(x<0)putchar('-'),x=~x+1;
	int top=0;
	do str[top++]=x%10,x/=10;while(x);
	while(top)putchar(str[--top]+48);
	if(sf^'#')putchar(sf);
}
using ll=long long;
constexpr int MOD=998244353;
int n,m;
int f[(1<<17)+5],g[(1<<17)+5];
int e[18][18];
int fac[17*17+5]={1};
void add(int&x,int y){
	x=x+y>=MOD?x+y-MOD:x+y;
}

signed main(){
	n=read(),m=read();
	for(int i=1;i<=n*n;++i)fac[i]=fac[i-1]*2%MOD;
	for(int i=1,u,v;i<=m;++i){
		u=read(),v=read();
		e[u][v]=e[v][u]=1;
	}
	for(int s=0,cnt;s<1<<n;++s){
		cnt=0;
		for(int i=1;i<=n;++i)
			if(s&(1<<(i-1)))
				for(int j=i+1;j<=n;++j)
					if(s&(1<<(j-1))&&e[n-i+1][n-j+1])
						++cnt;
		add(g[s],fac[cnt]);
	}
	for(int s=1<<(n-1),tmp;s<1<<n;++s){
		tmp=0;
		for(int t=s;t>=1<<(n-1);t=(t-1)&s)
			if(t^s&&t&(1<<(n-1)))
				add(tmp,(ll)f[t]*g[s^t]%MOD);
		f[s]=(g[s]-tmp+MOD)%MOD;
	}
	for(int i=2,ans;i<=n;++i){
		ans=0;
		for(int s=1<<(n-1);s<1<<n;++s)
			if(s&(1<<(n-i)))
				add(ans,(ll)f[s]*g[((1<<n)-1)^s]%MOD);
		write(ans);
	}
	return fw,0;
}

标签:连通,子图,mathit,题解,复杂度,这部分,个数,Connectivity,ABC213G
From: https://www.cnblogs.com/laoshan-plus/p/18468602

相关文章

  • [TJOI2018] 游园会 题解
    T7[TJOI2018]游园会只能说是道有意思的好题。一般来说遇到这种题我们想到的都会是设\(f_{i,\dots}\)表示长度为\(i\),然后后面跟一堆状态的情况。此题需要我们满足两个条件:LCS的长度;不能出现\(\texttt{NOI}\)的子串。第二个限制我们可以通过状态设计来解决,但第一个......
  • [JSOI2018] 潜入行动 题解
    T6[JSOI2018]潜入行动很套路、很裸的一道树形DP。看了状态就会推方程的那种。设\(f_{u,i,0/1,0/1}\)表示以\(u\)为根的子树中有\(i\)个监听器、\(u\)有没有监听器、\(u\)有没有被监听的方案数。显然要枚举子节点\(v\)、\(u\)的监听器数量\(i\)、\(v\)的监听器数......
  • [ABC213G] Connectivity 2 题解
    [ABC213G]Connectivity2题解套路的经典图上计数题。考虑枚举和\(1\)相连的子集\(S\)。答案显然由两部分构成,\(S\)集合和\(1\)相连的方案数\(f(S)\)和\(S\)对于\(G\)的补集所有的方案数\(g(S)\)。答案就是二者相乘。显然\(g\)更好处理。直接枚举集合的边即可......
  • P8386 [PA2021] Od deski do desk 题解
    P8386[PA2021]Oddeskidodesk题解考虑一个大的序列一定被分成几个区间来删除。朴素的dp定义是\(dp_{i,j}\)表示前\(i\)个数,最后一个数元素是\(j\)的方案数。然而这样不仅不好转移,而且设不下状态。不难发现所有值是等价的。考虑这样一个事情:若我们要分出一个新的区......
  • Project Euler 638 题解
    q-analog,老玩家集体起立!这也就是说:\[\binom{n+m}{n}_q=\sum_{\pi\inL_{n,m}}q^{area(\pi)}\]结束!#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintmod=1e9+7,maxn=2e7+5;intqp(inta,intb,intp=mod){ intres=1; while(b){ i......
  • 2024某校新生校队选拔赛题解
    游记某校某院与某院联合培养机制给排了两场讲座,讲完吃饭,讲座时间\(8:00-12:00,\)拖堂\(10\)min,到食堂\(10\)min,吃饭\(30\)min,走回去\(10\)min,打开网址发现时间只够看榜的一看榜我草\(5\)小时连\(4\)个题都做不出来翻题面发现A,L纯签到,B半签到,遂确信成分题解题目链接A验证是......
  • Project Euler 457 题解
    初等数论小题目求\[n^2-3n-1\equiv0\pmod{p^2}\]配方,得到:\[(2n-3)^2\equiv13\pmod{p^2}\]根据亨泽尔引理,只需得到\((2n-3)^2\equiv13\pmod{p}\)的解即可提升到\(p^2\)。这是二次剩余,直接解。单次求解\(O(\logn)\),时间复杂度\(O(n)\)。#include<bits/stdc++.h......
  • TopCoder SRM616 ColorfulCoins 题解
    TopCoderSRM616ColorfulCoins题意给一套货币,保证任意两种货币存在倍数关系且颜色互不相同。已知货币的币值集合,每次可以询问一个金额,给出货币张数最小的表示方案。问最小的询问次数,使得通过已知信息可以对应货币面值和颜色。分析最大的面值问一个\(\inf\)即可。这时只需要......
  • [ABC062C]/[ARC074A] Chocolate Bar 题解
    神秘分讨题(?总共\(4\)中情况。第一种:三个竖的并列:ans=min(ans,(h%3>0)*w);。第二种:三个横的并列:ans=min(ans,(w%3>0)*h);。第三种:一个横的矩形,然后是两个竖着的。For(i,1,h){ intfst=i*w; intscd=(w/2)*(h-i); intthd=(w%2>0)*(h-i)+(w/2)*(h-i); ans=min(ans......
  • 堆排序题解
    给定一个整数序列,请按非递减序输出采用堆排序的各趟排序后的结果。输入格式:测试数据有多组,处理到文件尾。每组测试数据第一行输入一个整数n(1≤n≤100),第二行输入n个整数。输出格式:对于每组测试,输出若干行,每行是一趟排序后的结果,每行的每两个数据之间留一个空格。输入样例......