题目链接

题目描述

给定一张强联通图,求有多少种边的存在情况满足图依然强联通。

\(n\leq15\)

Sol

首先正难则反,考虑用总数减去不强联通的。

考虑一张不强联通的图,缩点后一定是一个 DAG,好像可以对 DAG 进行计数。

诈一看这个做不了,因为缩点后计数是不可能在dp过程中实现的。

但我们按照 DAG 计数的思路的话其实并不需要真的知道 DAG 缩点后的形态。

我们类似 DAG 计数的话那么枚举这些缩完点后的点至少有多少个入度为 0 的点,然后容斥计算。

过程中我们用到的只是有 奇数/偶数个 入度为0的点的方案数以及他们和外部连边的总方案数。

所以我们只需要设 \(g[s]/h[s]\) 分别表示 集合 \(s\)的导出子图 内有 奇数/偶数 个入度为0的强联通分量的方案数。设 \(f[s]\) 表示 \(s\) 集合导出子图强联通的方案数,\(cnt(S,T)\) 表示 \(S\) 到 \(T\) 内的边数。

\(f\)的转移和 DAG 计数类似。g,h的转移都很简单:

\[f[S]=2^{cnt(S,S)}-\sum_{T\subseteq S , T \neq \emptyset}(g[T]-h[T])*2^{cnt(S-T,S-T)+cnt(T,S-T)}
\]

\[g[S]=\sum_{T\subseteq S,T\neq \emptyset} f[T]*h[S-T]
\]

\[h[S]=\sum_{T\subseteq S,T\neq \emptyset} f[T]*g[S-T]
\]

发现好像 \(g\),\(h\) 和 \(f\) 会互相转移。

分析一下,由于 \(g[0]=0\) 所以 \(h\) 的转移不受影响。然后 \(g[S]\) 的转移需要加上 \(f[S]\) , \(f[S]\) 的转移似乎也需要 \(g\) 来支持。

但是注意到我们算的东西是不强联通的,因此整个一大坨就是一个强联通分量的话是不能被算入 \(f\) 的,也就是说 \(g[S]\) 要靠 \(f[S]\) 来进行转移的部分恰好不能贡献到 \(f[S]\) 里面去,所以我们先算出 \(g\),\(h\) ,然后直接按照原来的方法算 \(f\) ,算完之后载把 \(f[S]\) 加入 \(g[S]\) 就可以了。

code:

#include<bits/stdc++.h>
#define Set(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MAXN=225;
const int N=16;
const int MAXS=1<<(N-1);
const int mod=1e9+7;
template <typename T> inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}
typedef long long ll;
template<typename T>inline void Inc(T&x,int y){x+=y;if(x>=mod) x-=mod;return;}
template<typename T>inline void Dec(T&x,int y){x-=y;if(x < 0) x+=mod;return;}
template<typename T>inline int fpow(int x,T k){int ret=1;for(;k;k>>=1,x=(ll)x*x%mod) if(k&1) ret=(ll)ret*x%mod;return ret;}
inline int Sum(int x,int y){x+=y;if(x>=mod) return x-mod;return x;}
inline int Dif(int x,int y){x-=y;if(x < 0 ) return x+mod;return x;}
int f[MAXS],g[MAXS],h[MAXS];
bitset<MAXN> in[MAXS],out[MAXS];
inline int Cnt(int S,int T){return (out[S]&in[T]).count();}
int bits[MAXN],cnt[MAXS];int n,m; int main()
{
init(n),init(m);bits[0]=1;
for(int i=1;i<MAXN;++i) bits[i]=Sum(bits[i-1],bits[i-1]);
const int UP=1<<n;
for(int i=1;i<=m;++i) {
int u,v;init(u),init(v);
for(int s=1;s<UP;++s) {
if(s&bits[u-1]) out[s].set(i);
if(s&bits[v-1]) in [s].set(i);
}
}f[0]=0,g[0]=0,h[0]=1;// g: odd / h: even for(int s=1;s<UP;++s) {
cnt[s]=cnt[s>>1]+(s&1);f[s]=0;int lb=s&(-s);
for(int t=s;t;t=(t-1)&s) if(t&lb) Inc(g[s],(ll)f[t]*h[s^t]%mod),Inc(h[s],(ll)f[t]*g[s^t]%mod);
for(int t=s;t;t=(t-1)&s) Inc(f[s],(ll)Dif(g[t],h[t])*bits[Cnt(t,s^t)+Cnt(s^t,s^t)]%mod);
f[s]=Dif(bits[Cnt(s,s)],f[s]);
Inc(g[s],f[s]);
}
printf("%d\n",f[UP-1]);
return 0;
}

【UOJ#37】 [清华集训2014] 主旋律的更多相关文章

  1. 【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理

    题目描述 求一张有向图的强连通生成子图的数目对 $10^9+7$ 取模的结果. 题解 状压dp+容斥原理 设 $f[i]$ 表示点集 $i$ 强连通生成子图的数目,容易想到使用总方案数 $2^{sum ...

  2. uoj #46[清华集训2014]玄学

    uoj 因为询问是关于一段连续区间内的操作的,所以对操作构建线段树,这里每个点维护若干个不交的区间,每个区间\((l,r,a,b)\)表示区间\([l,r]\)内的数要变成\(ax+b\) 每次把新操 ...

  3. UOJ.41.[清华集训2014]矩阵变换(稳定婚姻)

    题目链接 稳定婚姻问题:有n个男生n个女生,每个男/女生对每个女/男生有一个不同的喜爱程度.给每个人选择配偶. 若不存在 x,y未匹配,且x喜欢y胜过喜欢x当前的配偶,y喜欢x也胜过y当前的配偶 的完 ...

  4. bzoj 3816&&uoj #41. [清华集训2014]矩阵变换

    稳定婚姻问题: 有n个男生,n个女生,所有女生在每个男生眼里有个排名,反之一样. 将男生和女生两两配对,保证不会出现婚姻不稳定的问题. 即A-1,B-2 而A更喜欢2,2更喜欢A. 算法流程: 每次男 ...

  5. BZOJ3812 清华集训2014 主旋律

    直接求出强联通生成子图的数量较难,不妨用所有生成子图的数量减去非强联通的. 非强联通生成子图在所点后满足编号最小的点所在的强联通分量不是全集. 由于$n$很小,我们可以考虑状态压缩. 对于点集$S$, ...

  6. uoj 41 【清华集训2014】矩阵变换 婚姻稳定问题

    [清华集训2014]矩阵变换 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/41 Description 给出 ...

  7. AC日记——【清华集训2014】奇数国 uoj 38

    #38. [清华集训2014]奇数国 思路: 题目中的number与product不想冲: 即为number与product互素: 所以,求phi(product)即可: 除一个数等同于在模的意义下乘 ...

  8. [UOJ#274][清华集训2016]温暖会指引我们前行

    [UOJ#274][清华集训2016]温暖会指引我们前行 试题描述 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出无助的哀嚎 “冻死宝宝了!” 这时 远处的天边出现了一 ...

  9. UOJ#46. 【清华集训2014】玄学

    传送门 分析 清华集训真的不是人做的啊嘤嘤嘤 我们可以考虑按操作时间把每个操作存进线段树里 如果现在点x正好使一个整块区间的右端点则更新代表这个区间的点 我们不难发现一个区间会因为不同的操作被分成若干 ...

随机推荐

  1. 流程控制,循环结构,for,while循环

    '''1.变量名命名规范 -- 1.只能由数字.字母 及 _ 组成 -- 2.不能以数字开头 -- 3.不能与系统关键字重名 -- 4._开头有特殊含义 -- 5.__开头__结尾的变量,魔法变量 - ...

  2. 编译安装MySQL数据库

    1. 安cmake工具 # yum install -y cmake 2. 创建mysql用户 # useradd -M -s /sbin/nologin mysql 3. 创建数据目录 # mkdi ...

  3. Python pip升级及升级失败解决方案

    本教程用于Python  pip升级及失败解决方案 首先查看脚本 pip show pip 我已经升级到了最新的版本 安装其他模块过程中出现下面提示,便说明你需要升级pip You are using ...

  4. Eclipse新建新的工作空间,将原有的配置全部或部分复制

    1.部分复制 File->Switch workspace->Other...,按下图选择 只复制简单的配置,如cvs之类的信息是不会复制的. 2.全部复制(build path) 在1. ...

  5. default.html

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    1.nginx 配置模板 server { listen ; client_max_body_size 512M; proxy_set_header Connection ""; ...

  7. JDK下bin文件夹常见几个可执行文件

    bin目录下有很多的可执行文件: java.exe:运行Java程序,就是启动JVM,让JVM执行指定的编译后的代码: javac.exe:Java的编译器,它用于把Java源码文件(以.java后缀 ...

  8. json与String的转化

    String转成jsonObject    JsonObject   json = JsonObject.fromObject(String str) String转成JsonArray      J ...

  9. 摘抄大神对VUE 中slot-scope的深度理解

    Vue的slot-scope的场景的个人理解 这篇文章不是单纯把文档的话和api拿来翻译和演示,而是谈谈我对于slot-scope的使用场景的个人理解,如果理解错误,欢迎讨论! Vue的插槽slot, ...

  10. Dasha and Photos CodeForces - 761F (前缀优化)

    大意: 给定n*m初始字符矩阵, 有k个新矩阵, 第$i$个矩阵是由初始矩阵区间赋值得到的, 求选择一个新矩阵, 使得其余新矩阵到它距离和最小. 字符集比较小, 可以考虑每次区间覆盖对每个字符的贡献. ...