zoukankan      html  css  js  c++  java
  • [atARC105F]Lights Out on Connected Graph

    记$G[S]$表示图$G$在点集$S$上的导出子图,即$G[S]=(S,{(x,y)|x,yin S且(x,y)in E})$

    定义$g(S)$为所有$E'$(满足$E'subseteq G[S].E$)的图$G'=(S,E')$的染色方式之和,考虑枚举其中一种颜色的点集,则有$g(S)=sum_{Tsubseteq S}2^{|{(x,y)|(x,y)in E且xin T且yin C_{S}T}|}$(这些边可以选或不选)

    考虑计算$|{(x,y)|(x,y)in G[S].E且xin T且yin C_{S}T}|$,可以看作$S$中边数-$T$中边数-$C_{S}T$中边数,$o(2^{n}m)$预处理出$|G[S].E|$,那么即$|G[S].E|-|G[T].E|-|G[C_{S}T].E|$

    定义$f(S)$为有多少$E'$使得$E'subseteq G[S].E$且$G'=(S,E')$为好图,那么$f(V)$即为答案

    $f(S)$的计算略微比较复杂,定义$g'(S)$为所有不连通的$G'=(S,E')$(参考$g(S)$定义)的染色方式之和,容易发现有$f(S)=frac{g(S)-g'(S)}{2}$(联通二分图有2种染色方式)

    对于$g'(S)$,枚举$S$的某个$k$所属连通块,那么即有$g'(S)=sum_{kin T,Tsubset S}f(T)g(C_{S}T)$($k$为$S$中任意一个元素,注意这里$T e S$)

    上面的转移涉及到一个枚举子集的技巧,因此时间复杂度$o(3^{n}+2^{n}m)$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define M 1005
     5 #define mod 998244353
     6 int n,m,x,y,mi[M],e[M],se[N],g[N],f[N];
     7 int main(){
     8     scanf("%d%d",&n,&m);
     9     mi[0]=1;
    10     for(int i=1;i<=m;i++){
    11         scanf("%d%d",&x,&y);
    12         e[i]=((1<<x-1)|(1<<y-1));
    13         mi[i]=mi[i-1]*2%mod;
    14     }
    15     for(int i=0;i<(1<<n);i++)
    16         for(int j=1;j<=m;j++)se[i]+=((i&e[j])==e[j]);
    17     for(int i=0;i<(1<<n);i++){
    18         g[i]=1;
    19         for(int j=i;j;j=((j-1)&i))g[i]=(g[i]+mi[se[i]-se[j]-se[i^j]])%mod;
    20     }
    21     for(int i=0;i<(1<<n);i++){
    22         f[i]=g[i];
    23         int k=i-(i&(i-1));
    24         for(int j=i-k;j;j=((j-1)&i))
    25             if (j&k)f[i]=(f[i]+mod-1LL*f[j]*g[i^j]%mod)%mod;
    26     }
    27     printf("%lld",f[(1<<n)-1]*(mod+1LL)/2%mod);
    28 }
    View Code
  • 相关阅读:
    二维数组
    快速排序
    冒泡排序2
    对char类型数组的英文字母进行冒泡排序
    对char类型的数组进行冒泡排序
    冒泡排序
    对数组随机赋值,并输出(Arrays.toString(arr))
    数组声明的几种方式以及length属性
    猜拳游戏二
    二维小波包重构wprec2wprcoef
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13802165.html
Copyright © 2011-2022 走看看