[TC_SRM_460]TheCitiesAndRoadsDivOne

试题描述

John and Brus have become very famous people all over the world, especially in Bolivia. Once they decided to visit their fan club in Bolivia. John has an old map of Bolivia which shows all of its cities and the roads connecting them. All roads are bidirectional, meaning they can be traversed in both directions. Since the map is old, it's possible that some additional roads have been built since the map was produced. However, roads are never destroyed in Bolivia, so all the roads on the map still exist.

Brus has discovered on the Internet that each pair of Bolivian cities now has at least one and at most two simple paths connecting them. A path between cities \(A\) and \(B\) is a sequence of cities starting with \(A\) and ending with \(B\) such that there's a road between each pair of consecutive cities in the sequence. The path is considered simple if it consists of distinct cities.

John and Brus have decided to add some new roads to the old map in such a way that the resulting map satisfies this condition. They can only add a road between a pair of cities if that road did not already exist in the old map. They can't add more than one road between the same pair of cities, and they can't add a road that leads from a city to itself. All added roads must be bidirectional.

You are given a map. The \(j\)-th character of the \(i\)-th element of map will be Y if there is a road between the \(i\)-th and \(j\)-th cities on the old map, or N otherwise. Return the number of ways John and Brus can add new roads to the old map modulo \(1234567891\). Two ways are considered different if the sets of added roads are distinct. The order in which roads are added does not matter.

给一个 \(n\)(\(\le 20\))个节点的无向图,求加一些边使得图成为一棵树或者一棵单环树的方案数(答案对 \(1234567891\) 取模)。

输入

传给你一个 string[] 类型的参数

输出

返回一个整数表示答案

输入示例1

{"NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN", "NNNNNNNNNNNN"}

输出示例1

Returns: 1137797187

输入示例2

{"NYYNN", "YNYNN", "YYNNN", "NNNNY", "NNNYN"}

输出示例2

Returns: 6

数据规模及约定

见“试题描述”

题解

如果只需要组成树而不是单环树,那么就是明明的烦恼这题,prufer 序列即可,注意每个连通块缩成一个点后需要加权,因为它们大小不一。

这道题我们受它启发,当有一个环的时候,我们枚举哪些连通块组成了一个环,然后组成环的方案乘上接下来组成树的方案(仍可用 prufer 序列计算)就可以了。

注意这题有很多情况需分类讨论(以下只强调特殊情况):

  • 图中已经包含了一个环(这类情况中还需注意所有点都连成了同一个连通分量的情况);

  • 连成环的连通分量只有 \(1\) 个(如果这个连通分量大小小于 \(3\) 则不能用这个连通分量创造环);

  • 连城环的连通分量只有 \(2\) 个(需要考虑重边问题)。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i++)
#define dwn(i, s, t) for(int i = (s); i >= (t); i--) int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 25
#define maxs 1048576
#define MOD 1234567891
#define LL long long class TheCitiesAndRoadsDivOne {
private:
char str[maxn];
int n, fa[maxn], siz[maxn], Siz[maxn], cntb;
bool hasc[maxn];
int findset(int x) { return x == fa[x] ? x : fa[x] = findset(fa[x]); } LL Pow(int a, int b) {
LL ans = 1, t = a;
while(b) {
if(b & 1) (ans *= t) %= MOD;
(t *= t) %= MOD; b >>= 1;
}
return ans;
} int cbit[maxs], Log[maxs], fac[maxn]; public:
int find(vector <string> field) {
n = field.size();
fac[0] = 1;
rep(i, 1, n) fa[i] = i, siz[i] = 1, fac[i] = (LL)fac[i-1] * i % MOD;
rep(i, 1, n) {
strcpy(str + 1, field[i-1].c_str());
rep(j, 1, n) if(i < j && str[j] == 'Y') {
int u = findset(i), v = findset(j);
if(u == v) hasc[u] = 1;
else fa[v] = u, siz[u] += siz[v];
}
} bool cyc = 0;
rep(i, 1, n) if(findset(i) == i) Siz[cntb++] = siz[i], cyc |= hasc[i];
LL ans;
if(cntb == 1) ans = 1;
else {
ans = Pow(n, cntb - 2);
rep(i, 0, cntb - 1) (ans *= Siz[i]) %= MOD;
}
if(cyc) return ans; int all = (1 << cntb) - 1;
rep(s, 1, all) cbit[s] = cbit[s&~(s&-s)] + 1, Log[s] = s == 1 ? 0 : Log[s>>1] + 1;
rep(s, 1, all) {
LL tmp;
int csiz = 0, tot;
if(cbit[s] == 1) {
csiz = Siz[Log[s]];
if(csiz < 3) continue;
tmp = (((LL)csiz * (csiz - 1) >> 1) % MOD + MOD - csiz + 1) % MOD;
}
else if(cbit[s] == 2) {
int t1 = s & -s, t2 = (s ^ t1) & -(s ^ t1);
t1 = Log[t1]; t2 = Log[t2];
if(Siz[t1] == 1 && Siz[t2] == 1) continue;
csiz = Siz[t1] + Siz[t2];
tmp = (LL)Siz[t1] * Siz[t2] % MOD;
tmp = (tmp * (tmp - 1) >> 1) % MOD;
}
else {
tmp = 617283946ll * fac[cbit[s]-1] % MOD;
rep(i, 0, cntb - 1) if(s >> i & 1)
csiz += Siz[i], (tmp *= (LL)Siz[i] * Siz[i] % MOD) %= MOD;
}
tot = cntb - cbit[s] + 1;
if(tot > 1) {
(tmp *= Pow(n, tot - 2) % MOD * csiz % MOD) %= MOD;
rep(i, 0, cntb - 1) if(!(s >> i & 1)) (tmp *= Siz[i]) %= MOD;
}
(ans += tmp) %= MOD;
} return ans;
}
};

[TC_SRM_460]TheCitiesAndRoadsDivOne的更多相关文章

  1. topcoder srm 460 div1

    problem1 link 设$f[i][j]$表示已经分配了answers中的前$i$个,分配给的问题的状态为 $j$的方案数. 其中状态可以用$n$位的三进制表示,0表示还未分配,1表示已分配是 ...

随机推荐

  1. java基础编程——用两个栈来实现一个队列

    题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 题目代码 /** * <分析>: * 入队:将元素进栈A * 出队:判断栈B是否为空, * ...

  2. 关于HTML(含HTML5)的块级元素和行级(内联)元素总结

    1.首先我们要知道什么是块级元素和行级(内联)元素? 块级(block)元素的特点: ①总是在新行上开始: ②高度,行高以及外边距和内边距都可控制: ③宽度缺省是它的容器的100%,除非设定一个宽度: ...

  3. vue学习之路 - 3.基本操作(中)

    基本操作(中) 本章节主要介绍:vue的条件渲染.列表渲染,计算属性和侦听器 条件渲染和列表渲染 条件渲染主要使用到了 v-if 指令,列表渲染主要使用了 v-for 指令. 下面介绍 v-if .  ...

  4. 九、Linux 磁盘管理

    Linux 磁盘管理 Linux磁盘管理好坏直接关系到整个系统的性能问题. Linux磁盘管理常用三个命令为df.du和fdisk. df:列出文件系统的整体磁盘使用量 du:检查磁盘空间使用量 fd ...

  5. .pyc是什么鬼

    .pyc是个什么鬼? 1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存 ...

  6. h5中的video与audio

    ·首先带大家熟悉一下video标签的属性方法,根据属性方法做一个小demo, HTML5支持的视频格式: Ogg 带有Theora视频编码+Ogg文件 支持的浏览器:F.O MEPG4  带有H.26 ...

  7. 22.VUE学习之-replice删除当前评论条数

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 如何用eclipse运行导入的maven项目

    1.配置jdk系统环境变量.找到安装的jdk的安装目录,新建系统环境变量,变量名为JAVA_HOME(作为一个引用),变量值为该路径. 找到Path,将%JAVA_HOME%/bin; 添加到变量值的 ...

  9. haystack(django的全文检索模块)

    haystack haystack是django开源的全文搜索框架 全文检索:标题可以检索,内容也可以检索 支持solr ,elasticsearch,whoosh 1.注册app 在setting. ...

  10. 自动化运维之使用Python3收发电子邮件~~~附源码

    一.背景介绍   1.1  一些专业名称的解释 MUA——Mail User Agent,邮件用户代理.是用户与电子邮件系统的交互接口,一般来说它就是我们PC机上的一个程序,提供一个好的用户界面,它提 ...