1 条题解
-
0
好题。
I. 染色
枚举边复杂度显然过高,考虑枚举点。在点上,二分图有个很好的性质:有且仅有二分图能进行黑白染色。对应地,一个连通图的黑白染色方案一一对应一个极大可行边(不使其有奇环——即连接异色点的边)集合。
遂考虑转化为对每个点集的每个染色方案计数。
II. 连通?
连通很难限制,假设暂时放弃连通。设 表示点集 所有染色方案对应的可行边方案数。可以枚举子集确定染色方案。若 为黑点集,则对应的可行边方案数为 ,其中 为点集 内部连接的边数。
但是,我们仍需求出连通的方案数。考虑钦点在某个顺序下“第一个”连通块 ,只要让 与剩下的点不连通,就可以减掉这些方案。这里可以设 含有 中标号最小的点。设 为连通点集 的相应方案数,则有 。
于是本题就做完了。值得注意的是,黑白染色可以翻转,因此最后答案要除以 。
const int N = 17; const ll P = 998244353; int n, m, s, S; inline int lowbit(int x) { return x & -x; } ll f[1 << N], g[1 << N], pw[N * N]; int cnt[1 << N]; int main() { pw[0] = 1; U (i, 1, N * N - 1) pw[i] = pw[i - 1] * 2 % P; rd(n, m); S = (1 << n); U (i, 1, m) { int u, v; rd(u, v); --u; --v; for (s = 0; s < S; ++s) if (((s >> u) & 1) && ((s >> v) & 1)) ++cnt[s]; // 点集 s 的边数和 } for (s = 0; s < S; ++s) { g[s] = 1; // 全白点 for (int t = s; t; (--t) &= s) (g[s] += pw[cnt[s] - cnt[t] - cnt[s ^ t]]) %= P; } for (s = 0; s < S; ++s) { f[s] = g[s]; for (int t = s; t; (--t) &= s) if (lowbit(s ^ t) > lowbit(t)) // 钦点 t 是含有标号最小的点的连通块 (f[s] -= f[t] * g[s ^ t] % P - P) %= P; } printf("%lld", f[S - 1] * ((P + 1) >> 1) % P); } // LUOGU_RID: 204624807 #include <bits/stdc++.h> using namespace std; #define ll long long #define mod 998244353 ll n,m,u,v,cnt[1<<17],f[1<<17],g[1<<17],pw[444]; int main(){ cin>>n>>m; pw[0]=1; for(int i=1;i<=m;i++){ pw[i]=pw[i-1]*2%mod; cin>>u>>v; u--,v--; for(int S=0;S<1<<n;S++) if((S>>u&1)&&(S>>v&1)) cnt[S]++; } for(int S=0;S<1<<n;S++){ g[S]=1; for(int T=S;T;T=S&T-1) g[S]=(g[S]+pw[cnt[S]-cnt[T]-cnt[S^T]]); f[S]=g[S]; int t=S&S-1; for(int T=t;T;T=t&T-1) f[S]=(f[S]-g[T]*f[S^T])%mod; } cout<<(f[(1<<n)-1]*(mod+1>>1)%mod+mod)%mod; return 0; }
- 1
信息
- ID
- 9342
- 时间
- 3000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 6
- 已通过
- 3
- 上传者