hdu5304 Eastest Magical Day Seep Group's Summer 状压dp+生成树
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5304
16个点的无向图,问能生成多少个n条边的连通图。(即多一条边的树)
先n^3 * 2^n 枚举全部的环。状压dp即可。dp[i][j]表示以i为终点,走了j状态集合的方案数。要枚举起点,每次走比起点大的点。所以要n^3 2^n枚举。
把环压缩成点。构造基尔霍夫矩阵。每种状态下n^3求生成树。
故总复杂度是 n^3 * 2^n + n^3 * 2^n
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
const int N = (1<<16)+10;
ll ans;
int f[N],dp[20][N];
bool d[20][20];
int n,m; ll exgcd(ll a,ll b,ll &x,ll &y)//乘法逆元返回的d是a,b的公约数。x是a mod b的逆元
{
if(b==0)
{
x=1ll;y=0;
return a;
}
ll d=exgcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-a/b*y;
return d;
} ll Gauss(int C[][20],int n)//计算n阶行列式的绝对值 % mod
{
ll ans=1ll;
int flag=1;//行列交换的次数
int i,j,k;
for(i=0;i<n;i++)
{
if(C[i][i]==0)
{
for(j=i+1;j<n;j++)
if(C[j][i])break;
if(j==n)return 0;//某列的值全是0的ans=0。
flag=!flag;
for(int k=i;k<n;k++)
swap(C[i][k],C[j][k]);//i和j行交换
}
ans=ans*C[i][i]%mod;//对角线相乘
ll x,y;
int tp=exgcd(C[i][i],mod,x,y);//x为逆元 for(k=i+1;k<n;k++)
C[i][k]=C[i][k]*x%mod; for(int j=i+1;j<n;j++)
for(int k=i+1;k<n;k++)
{
C[j][k]=(C[j][k]-(ll)C[j][i]*C[i][k])%mod;
if(j==k)
C[j][k]=(C[j][k]+mod)%mod;
}
for(k=i+1;k<n;k++)
C[i][k]=(ll)C[i][k]*C[i][i]%mod; } ans=(ans%mod+mod)%mod;
if(flag) return ans;
else return mod-ans;
} ll solve(int s){
int Kir[20][20];
int vis[20],col[20];
memset(Kir,0,sizeof(Kir));
memset(vis,0,sizeof(vis));
memset(col,-1,sizeof(col));
for(int i=0;i<n;i++)
if((1<<i)&s) vis[i]=1;
int num=0;
for(int i=0;i<n;i++)if(!vis[i])
col[i]=num++;
for(int i=0;i<n;i++)if(vis[i])
col[i]=num;
num++; for(int i=0;i<n;i++)
for(int j=0;j<n;j++)if(i!=j && col[i]!=col[j])
Kir[col[i]][col[j]] -= d[i][j];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)if(col[i]!=col[j])
Kir[col[i]][col[i]] += d[i][j]; return Gauss(Kir,num-1);
} int main(){
// freopen("e.in","r",stdin);
// freopen("my05.out","w",stdout);
while(scanf("%d%d",&n,&m)!=EOF){
ans = 0;
memset(d,0,sizeof(d));
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
u--,v--;
d[u][v] = d[v][u] = 1;
} memset(f,0,sizeof(f));
for(int st=0;st<n;st++){
memset(dp,0,sizeof(dp));
dp[st][(1<<st)] = 1;
for(int s=1;s<(1<<n);s++)if((1<<st)&s){
for(int i=0;i<n;i++)if(i>=st)
if(dp[i][s]){
for(int j=st+1;j<n;j++)
if( (s&(1<<j))==0 && d[i][j] )
dp[j][s|(1<<j)] = ( dp[i][s] + dp[j][s|(1<<j)])%mod;
if(d[i][st])
f[s] = ( dp[i][s] + f[s] )%mod;
}
}
} ll inv2 = (mod+1)/2;
for(int i=1;i<(1<<n);i++){
if(f[i]){
int co = 0;
for(int j=0;j<n;j++)if((1<<j)&i) co++;
if(co<=2) continue;
f[i] = ((ll)f[i]*inv2)%mod;
ans = (ans + (ll)f[i]*solve(i)%mod )%mod;
}
} printf("%I64d\n",ans); } return 0;
}
hdu5304 Eastest Magical Day Seep Group's Summer 状压dp+生成树的更多相关文章
- HDU 5304(Eastest Magical Day Seep Group's Summer-环加外向树生成树计数)[Template:Kirchhoff矩阵]
Eastest Magical Day Seep Group's Summer Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 655 ...
- uva 11825 Hackers' Crackdown (状压dp,子集枚举)
题目链接:uva 11825 题意: 你是一个黑客,侵入了n台计算机(每台计算机有同样的n种服务),对每台计算机,你能够选择终止一项服务,则他与其相邻的这项服务都终止.你的目标是让很多其它的服务瘫痪( ...
- 状压dp Mondriaan's Dream poj2411
超经典的一道题目,实现这题的方法也有非常多种 1.利用DFS建立矩阵,然后通过高速矩阵幂得到答案(运用于min(m,n)比較小.可是max(m,n)很大的情况) 2.利用dp状压解决 第一种在我的还有 ...
- group:状压dp,轮廓线
神仙题.但是难得的傻孩子cbx没有喊题解,所以也就难得的自己想出来了一个如此神仙的题. 如果是自己想的,说它神仙是不是有点不合适啊..? 反正的确不好像.关键就在于这个标签.颓完标签就差不多会了. % ...
- group 状压dp
应某些人要求,我把标签删掉了 这是一道好题. 一看$c<=16$果断状压,但是怎么压? 一个很显然的思路是,枚举上下两层的状态,每一层的状态极限有$C(c,c/2)$,c=16的时候有13000 ...
- [杂题]:group(状压DP+轮廓线)
题目描述 $pure$在玩一个战略类游戏.现在有一个士兵方阵,每行有若干士兵,每个士兵属于某个兵种.行的顺序不可改变,且每一行中士兵的顺序也不可改变.但由于每一行都有$C$个位置($C$不小于任一行的 ...
- [生产环境数据恢复]innobackupex: fatal error: OR no 'datadir' option in group 'mysqld' in MySQL options
1 运行恢复命令 [xxx@xxx-c001db1 tmp]$ time /usr/bin/innobackupex --rsync --user="user" --passwo ...
- hdu 4638 Group(离线+树状数组)
Group Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- UVA 1484 - Alice and Bob's Trip(树形DP)
题目链接:1484 - Alice and Bob's Trip 题意:BOB和ALICE这对狗男女在一颗树上走,BOB先走,BOB要尽量使得总路径权和大,ALICE要小,可是有个条件,就是路径权值总 ...
随机推荐
- Js的闭包,这篇写的是比较清晰明了的
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- 经典面试题: 从输入URL到页面加载的过程发生了什么?
可以分为这几个大的过程: DNS解析 TCP连接 客户端发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 结束 其中(1)DNS解析可以理解为主寻找这个IP地址的过程,其中如果找 ...
- C#中的DBNull、Null、""和String.Empty
1.对DBNull的解释: 该类用于指示不存在某个已知值(通常在数据库应用程序中). 在数据库应用程序中,空对象是字段的有效值.该类区分空值(空对象)和未初始化值(DBNull.Va ...
- Redis轻快入门
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作由VMware主 ...
- 二:SQL映射文件
二:SQL映射文件 1.SQL映射文件: (1)mapper:映射文件的根元素节点,只有一个属性namespace(命名空间) 作用:用于区分不同的mapper全局唯一 绑定dao接口即面向接口编程, ...
- web前端-----第二弹CSS
web前端之CSS样式 CSS 语法 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. ''' selector { property: value; property: value; ...
- Hi3518EV200平台ADC多通道采样
Hi3518EV200平台ADC多通道采样流程 Hi3518EV200 ADC 本文针对Hi3518EV200平台处理器,通过ADC单次采样方式,实现对多通道(1~4通道)ADC进行采样控制.本文仅仅 ...
- JAVA提高十四:HashSet深入分析
前面我们介绍了HashMap,Hashtable,那么还有一个hash家族,那就是HashSet;在讲解HashSet前,大家先要知道的是HashSet是单值集合的接口,即是Collection下面的 ...
- AIO5程序中审批跳转条件:超过某一个值必须总经理审批
以实际需求为例看下系统中如何设置: 客户需求:采购订单中对总金额进行限制,超过20000的话必须要经过总经理审批含税金额<20000:采购部门某个员工发起→直接主管批→财务主管知会含税金额≥20 ...
- JavaScript学习心得
javaScript十分的强大,所以自然而然学起来也是不易的,想要掌握它的核心,把它理解透更是不易的,但只要你能够静下心来,耐心的去钻研,学习,还是可以把它给学好的,加油吧! 下面是一些JavaScr ...