hdu 4997 Biconnected
这题主要是计算连通子图的个数(c)和不连通子图的个数(dc)还有连通度为1的子图的个数(c1)和连通度为2以上的子图的个数(c2)之间的转化关系
主要思路大概例如以下:
用状态压缩的方法算出状态为x的子图的不连通子图个数dc[x],dc[x] = ∑ c[i]*(2^edge[x-i]),i为x的子集且i中有x的编号最小的元素。edge[x] 表示x集合内有几条边
连通子图个数c[x] = 2^edge[x] - dc[x]
想得到双连通子图的个数就要计算单连通子图的个数
单连通子图缩块后是一棵树,假设每次我们选择标号最小的点所在的块为根节点(块)
那么单连通子图能够看成是在这个双连通的根节点(块)的基础上连接一个连通分量。这样能枚举到全部的情况,也不会反复
mc[s][x] += mc[s][x - y] * c[y] * e[s][y]。当中mc[s][x-y]是指把x-y连接到s的方法数,e[s][y]是指s到y的边数
c1[s] += mc[x][s - x],c1[s]是s中单连通子图的个数
而双连通子图个数 c2[s] = c[s] - c1[s]
最后转回去计算mc[s][0]。意思假设根节点s(块)不拓展连通分量的方法数,就相当于计算根节点(块)为双连通子图的方法数。等于c2[s]
再通过这些值计算mc[s+1][?]的值,不断的往上递推来完毕所有的计算
#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<cassert>
#include<cstring>
#include<iomanip>
using namespace std;
#ifdef _WIN32
#define i64 __int64
#define out64 "%I64d\n"
#define in64 "%I64d"
#else
#define i64 long long
#define out64 "%lld\n"
#define in64 "%lld"
#endif
/************ for topcoder by zz1215 *******************/
#define foreach(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
#define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++)
#define FF(i,a) for( int i = 0 ; i < (a) ; i ++)
#define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --)
#define S64(a) scanf(in64,&a)
#define SS(a) scanf("%d",&a)
#define LL(a) ((a)<<1)
#define RR(a) (((a)<<1)+1)
#define pb push_back
#define pf push_front
#define X first
#define Y second
#define CL(Q) while(!Q.empty())Q.pop()
#define MM(name,what) memset(name,what,sizeof(name))
#define MC(a,b) memcpy(a,b,sizeof(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define read freopen("out.txt","r",stdin)
#define write freopen("out2.txt","w",stdout)const int inf = 0x3f3f3f3f;
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;
const double oo = 10e9;
const double eps = 10e-9;
const double pi = acos(-1.0);
const int mod = 1000000007;
const int maxn = 1 << 10;int n, m;
int a[10][10];
i64 pow2[maxn];
i64 edge[maxn];
i64 ex[10][maxn];
i64 e[maxn][maxn];
i64 dc[maxn];
i64 c[maxn];
i64 c1[maxn];
i64 c2[maxn];
i64 mc[maxn][maxn];
vector<int>vx;
vector<int>v;
vector<int>v2;void start(){MM(edge, 0); MM(dc, 0); MM(c, 0); MM(c1, 0); MM(c2, 0); MM(e, 0); MM(ex, 0); MM(mc, 0);for (int x = 0; x < n; x++){for (int s = 0; s < (1 << n); s++){for (int i = 0; i < n; i++)if (s&(1 << i)){if (!a[x][i]){ex[x][s] ++;}}}}for (int s = 0; s < (1<<n); s++){for (int x = 0; x < (1 << n); x++){for (int i = 0; i < n; i++)if(s&(1<<i)){e[s][x] += ex[i][x];}}}for (int s = 1;s < (1 << n); s++){for (int i = 0; i < n; i++) if(s & (1<<i)){for (int j = i + 1; j < n; j++) if(s& (1<<j)){if (!a[i][j]){edge[s]++;}}}}int head;for (int s = 1; s < (1 << n); s++){v.clear();for (int i = 0; i < n; i++){if (s & (1 << i)){v.push_back((1<<i));}}head = v[0];v.erase(v.begin());int x;for (int i = 0; i < (1 << ((int)v.size())); i++){x = 0;for (int pos = 0; pos < v.size(); pos++){if (i &(1 << pos)) {x += v[pos];}}x += head;if (x != s){dc[s] += c[x] * pow2[edge[s - x]];dc[s] %= mod;}} c[s] = pow2[edge[s]] - dc[s] + mod;c[s] %= mod; }for (int s = 1; s < (1 << n); s++){vx.clear();v.clear(); int x;for (int i = 0; i < n; i++){if (s & (1 << i)){vx.push_back(1<<i);}}int vxhead = vx[0];vx.erase(vx.begin());for (int i = 0; i < (1 << ((int)vx.size())); i++){x = 0;for (int pos = 0; pos < vx.size(); pos++){if (i&(1 << pos)){x += vx[pos];}}x += vxhead;if (x != s){c1[s] += mc[x][s - x];c1[s] %= mod;}}c2[s] = (c[s] - c1[s]+mod)%mod;mc[s][0] = c2[s];for (int i = 0; i < n; i++){if (s&(1 << i)){head = i;break;}}for (int i = head + 1; i < n; i++){if (!(s&(1 << i))){v.push_back(1<<i);}}for (int i = 1; i < (1 << ((int)v.size())); i++){x = 0;for (int pos = 0; pos < v.size(); pos++){if (i&(1 << pos)){x += v[pos];}}v2.clear();for (int u = 0; u < n; u++){if (x&(1 << u)){v2.push_back(1 << u);}}int y;for (int j = 1; j < (1 << ((int)v2.size())); j++) if(j&1){y = 0;for (int pos = 0; pos < v2.size(); pos++){if (j & (1 << pos)){y += v2[pos];}}mc[s][x] +=(( mc[s][x - y] * c[y])%mod) * e[s][y];mc[s][x] %= mod;}}}}int main(){pow2[0] = 1;for (int i = 1; i < maxn; i++){pow2[i] = pow2[i - 1] * 2;pow2[i] %= mod;}int T;cin >> T;while (T--){cin >> n >> m;MM(a, 0);int x, y;for (int i = 0; i < n; i++){a[i][i] = 1;}for (int i = 1; i <= m; i++){cin >> x >> y;x--; y--;a[x][y] = a[y][x] = 1;}start();cout << c2[(1 << n) - 1] << endl;}return 0;
}
转载于:https://www.cnblogs.com/gcczhongduan/p/5206026.html
hdu 4997 Biconnected相关推荐
- HDU 4997 Biconnected (状态压缩DP)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4997 题意:一个n个点的完全图中去掉一些边.求这个图有多少个子图是边双联通的.(就是去掉任意一条边之后 ...
- HDU 4389 - X mod f(x)
题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4389 2012多校,第9场,1010 . 问题是,询问区间内 存在多少个 哈沙德数(Harshad ...
- hdu 4389 囧,打表
http://acm.hdu.edu.cn/showproblem.php?pid=4389 题意 :一个数能被他各个位数之和整除则符合要求,给L,R,问区间里有多少个数符合要求. 囧,居然打表就能过 ...
- HDU——1106排序(istringstream的使用、STLvector练习)
排序 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- hdu 5438 Ponds 拓扑排序
Ponds Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/contests/contest_showproblem ...
- HDU 1248 寒冰王座(全然背包:入门题)
HDU 1248 寒冰王座(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid=1248 题意: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票 ...
- hdu 1312 Red and Black 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1312 第二条深搜,题目并不难,但是做了我好久好久,由于一个细节,让我赌上了一个晚上的时间. 题目大意: ...
- HDU 1429 胜利大逃亡(续) (BFS+位压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) ...
- hdu 1272 小希的迷宫
Problem Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该 ...
最新文章
- python数据分析(九)-点积与线性代数
- asp.net代码审计起始篇之系统搭建
- .net aes加密视频等文件
- SQL Server 2016 JSON原生支持实例说明
- 计算机沟通方式,雅思阅读练习:计算机改变沟通方式
- windows下配置caffe-matlab接口
- php curl post登录与带cookie模拟登录随笔
- TTS Service Extended (进程:com.google.tts)意外停止 恢复被阉割的TTS文字转语音功能
- 熟悉JDK8新特性,“Lambda表达式与函数式接口”
- 258. Move 0s To The End I -- Laicode
- matlab中适应度函数怎么编写,matlab常用的几个适应度评价函数
- 物理模拟重力 斜抛运动计算 抛物线计算
- 服务器w7系统怎么开启端口,win7如何打开21端口|win7开启21端口的方法
- 子网掩码及其与IP地址、网关的关系
- java中线,使用Voronoi图查找多边形的中线
- 红利逐渐消失殆尽的互联网下半场,前路何方?
- java 获取浏览器名称及版本号
- GitOps 与 ChatOps 的落地实践
- Python之Datasets库安装报错的解决方法
- 【uni-app框架介绍及环境配置】
热门文章
- QEMU的基本使用方法(MIPS)
- CentOS7部署Subversion服务器和TortoiseSVN客户端简记
- MQ-2烟雾浓度传感器(STM32F103)
- 词嵌入矩阵(Word Embeddings)的生成
- 智能无纸化办公,方便快捷,DIY也很简单
- 樱桃牌-高逼格键盘敲代码贼爽!包邮送你!
- 在 Ubuntu 上添加或删除 PPA 存储库
- 黑客零基础入门教程,从入门到精通学习路线规划,看完这篇就够了。
- python无法启动此程序丢失zlib.dll_关于winserver2012运行c++程序缺少dll的理由
- WinImage 8.10注册算法简单分析