当前位置: 首页 > news >正文

hdu5304 Eastest Magical Day Seep Group#39;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;
}


转载于:https://www.cnblogs.com/zsychanpin/p/6938111.html

相关文章:

  • Visual Studio - 引入动态库
  • iOS private-api-checker私有API检测
  • JAVA常见算法题(十二)
  • 指针知识梳理10-指向数组的指针
  • Python入门基础:代码的编码风格
  • 中科院分词系统(NLPIR)JAVA简易教程
  • 62.Unique Paths
  • HttpClient调用api
  • 如何选择版本控制系统之三---代码托管操作
  • UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)
  • 隐马尔科夫模型HMM(四)维特比算法解码隐藏状态序列
  • Java - byte[] 和 String互相转换
  • 1.5在linux下新增大于2T的硬盘在linux下挂载操作
  • Mybatis在oracle批量更新
  • visual studio for mac在线安装网络错误
  • C++类中的特殊成员函数
  • css选择器
  • Java基本数据类型之Number
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • PHP 的 SAPI 是个什么东西
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 分布式熔断降级平台aegis
  • 机器学习 vs. 深度学习
  • 算法之不定期更新(一)(2018-04-12)
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (java)关于Thread的挂起和恢复
  • (rabbitmq的高级特性)消息可靠性
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • .NET CLR基本术语
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .net 获取url的方法
  • .NetCore项目nginx发布
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • ?php echo $logosrc[0];?,如何在一行中显示logo和标题?
  • @data注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce
  • [BUUCTF]-PWN:wustctf2020_number_game解析(补码,整数漏洞)
  • [C#]使用PaddleInference图片旋转四种角度检测
  • [codeforces]Levko and Permutation
  • [LeetCode] NO. 169 Majority Element
  • [MT8766][Android12] 取消WIFI热点超过10分钟没有连接自动关闭设定
  • [NOIP2014] 提高组 洛谷P1941 飞扬的小鸟
  • [python]用python获取EXCEL文件内容并保存到DBC
  • [rancher] rancher部署和使用的一些思考
  • [SDUT](3361) 数据结构实验之图论四:迷宫探索 ---DFS(图)
  • [Unity3d for android]屏幕触摸事件
  • [web相关]解决MSVCR100.dll丢失的问题 (WAMP安装后不能启动)
  • [创业之路-99/管理者与领导者-141] :绩效管理-1-绩效管理是一把手工程、是系统工程、是化繁为简工程
  • [架构之路-249]:目标系统 - 设计方法 - 软件工程 - 需求工程- 需求开发:如何用图形表达需求,结构化方法的需求分析
  • [蓝桥杯 2018省赛]回家路费