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要小,可是有个条件,就是路径权值总 ...
随机推荐
- 3Sum探讨(Java)
探讨一下leetcode上的3Sum: Given an array S of n integers, are there elements a, b, c in S such that a + b ...
- Linux常用配置讲解
本文主要讲解Linux的用户设置.主机名设置.网络配置.防火墙配置 用户传输包的命令lrzsz的安装以及SSH服务配置等基本操作. 1. 用户名设置 服务肯定是为了用户,而用户可能对于Linux并不了 ...
- jenkins~管道Pipeline的使用,再见jenkinsUI
Pipeline在Jenkins里的作用 最近一直在使用jenkins进行自动化部署的工作,开始觉得很爽,省去了很多重复的工作,它帮助我自动拉服务器的代码,自动还原包包,自动编译项目,自动发布项目,自 ...
- Hive详解
1. Hive基本概念 1.1 Hive简介 1.1.1 什么是Hive Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能. 1.1 ...
- Python学习一
安装时遇到的问题 安装anaconda3.0到D盘之后,配置好两个环境变量:D:\anaconda和D:\anaconda\Scripts.发现在命令行中执行python指令可以,但conda指令却是 ...
- 【转】【JAVA应用】多线程断点下载
[转自] 光仔December http://blog.csdn.net/acmman 问题:多线程下载的好处? 多线程下载比单线程下载快,主要的原因是采用多线程下载,可以抢占更多的服务器资源.抢占C ...
- js 与 ios Android交互
一.android 交互 1.js调用webview 在android API Level 17及以上的版本中,就会出现js调用不了android的代码,这是版本兼容的问题,需要在调用的方法上面加一个 ...
- python爬虫实战 获取豆瓣排名前250的电影信息--基于正则表达式
一.项目目标 爬取豆瓣TOP250电影的评分.评价人数.短评等信息,并在其保存在txt文件中,html解析方式基于正则表达式 二.确定页面内容 爬虫地址:https://movie.douban.co ...
- Java快速扫盲指南
文章转自:https://segmentfault.com/a/1190000004817465#articleHeader22 JDK,JRE和 JVM 的区别 JVM:java 虚拟机,负责将编译 ...
- file-loader 使用心得
将webpack 里面的图片文件都放在制定文件夹. 配置如下 { test: /\.png$/, loader: "file-loader?name=imgs/[name]-[hash].[ ...