zoukankan      html  css  js  c++  java
  • 金阙前开二峰长

    根据题目对于合法图的要求,假设当前有$k$个连通块,则边数不能超过$n-k+1$。
    这说明最多有一个连通块是环套树,其他都是树。
    先统计一个集合$s$内可以构成环的数量。
    设$f_{s,i}$表示s集合内,当前走到点$i$的环的数量。
    如果接下来枚举的环的节点都$>=s$的lowbit,则每一个环恰好会在最小的点以顺时针/逆时针的方向计算2次。
    初值$f_{{i},i}=1$
    接下来枚举往哪里走,设为j。则$f_{s+{j},j}+=f_{s,i}$
    设$c_{s}$为s集合构成的环数,则$c$可以按照定义从$f$得来。
    接下来枚举大小$>2$(简单环)$s$表示唯一的环。把$s$缩成一个点。
    使用矩阵树定理。建一个超级源点$st$朝缩点后图的每一个点连边。
    如果这个点是被缩的,则边权设为$s$的大小,否则设为$1$,求解所有生成树的权值之积的和就是求图中有$s$这个环的符合题目要求的子图的个数。
    为什么?一棵生成树包含了从$st$连出来的一些边和原图的一些边,如果只考虑原图的边的话,原图的边构成了森林。
    考虑森林中的一棵树$t$,则$st$有$card(t)$种方式向t连边。
    而且如果要让整个图连通,且不能使用缩点后图的其他边,则$st$必须要向森林的每个连通块连边。连边的方式有森林大小$*$权值(被缩过的点拥有)种,恰好就是题目要求的贡献。
    时间复杂度$O(2^n imes n^3)$

  • 相关阅读:
    [c++]在类中定义常量的几个做法
    VC6中使用高版本系统API的方法
    Delphi编程中实现窗口分割
    Win32 SDK窗口程序代码(含详细注释)
    [c++]在C++中定义常量的两种方法的比较
    VC6里的_WIN32_WINNT宏
    [VC]自己实现TRACE功能
    [delphi]保证程序只运行一个实例
    转载:C# 设置文件夹权限(代码简单)
    VC:动态链接库
  • 原文地址:https://www.cnblogs.com/cszmc2004/p/13175093.html
Copyright © 2011-2022 走看看