_bzoj1016 [JSOI2008]最小生成树计数【生成树】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1016
其实原题不叫这个的,而且原题是有一个背景故事的。。。
首先,容易得知,一个最小生成树不管是什么样的,同一种长度的边出现的次数是一样的。而且由Kruscal的过程,若当前节点对整个图减少一个联通块有贡献,则加这条边,也就是说在比当前边短的边已经全部考虑完后,与当前边一样长的所有边对整个图的连通性的贡献是一样的。则,若最小生成树中与当前边一样长的边出现了x次,共有tot条,那么暴力枚举C(tot, x)次,若它们不构成环,则是合法的。最后对每种长度的边乘法原理一下就ok咯~
注意题目陷阱:原图有可能没有生成树,此时输出0!
#include <cstdio>
#include <algorithm>
#include <cstring> const int maxn = 105, maxm = 1005, mod = 31011; int n, m, fa[maxn], num[maxm], cnt, t_fa[15][maxn], idx, fu, fv, ans, t_ans;
int head[maxm], to[maxm], next[maxm], lb, max_step;
struct Edge {
int u, v, ww, w;
} a[maxm]; bool cmp(const Edge & aa, const Edge & ss) {
return aa.ww < ss.ww;
}
int getfa(int * ff, int aa) {
return ff[aa] == aa? aa: ff[aa] = getfa(ff, ff[aa]);
}
inline void ist(int aa, int ss) {
to[lb] = ss;
next[lb] = head[aa];
head[aa] = lb;
++lb;
}
void dfs(int step, int now) {
if (step == max_step) {
++t_ans;
return;
}
for (int j = next[now]; j != -1; j = next[j]) {
fu = getfa(t_fa[step - 1], a[to[j]].u);
fv = getfa(t_fa[step - 1], a[to[j]].v);
if (fu == fv) {
continue;
}
memcpy(t_fa[step], t_fa[step - 1], sizeof fa);
t_fa[step][fu] = fv;
dfs(step + 1, j);
}
} int main(void) {
//freopen("in.txt", "r", stdin);
memset(head, -1, sizeof head);
memset(next, -1, sizeof next);
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
fa[i] = i;
}
for (int i = 0; i < m; ++i) {
scanf("%d%d%d", &a[i].u, &a[i].v, &a[i].ww);
}
std::sort(a, a + m, cmp);
a[0].w = 1;
idx = 1;
ist(1, 0);
for (int i = 1; i < m; ++i) {
if (a[i].ww == a[i - 1].ww) {
a[i].w = idx;
}
else {
a[i].w = ++idx;
}
ist(a[i].w, i);
} memcpy(t_fa[0], fa, sizeof fa);
for (int i = 0; i < m; ++i) {
fu = getfa(fa, a[i].u);
fv = getfa(fa, a[i].v);
if (fu != fv) {
fa[fu] = fv;
++num[a[i].w];
if (++cnt == n - 1) {
break;
}
}
}
if (cnt < n - 1) {
puts("0");
return 0;
}
memcpy(fa, t_fa[0], sizeof fa); ans = 1;
for (int i = 1; i <= n; ++i) {
fa[i] = i;
}
for (int i = 1; i <= idx; ++i) {
if (!num[i]) {
continue;
}
max_step = num[i];
t_ans = 0;
for (int j = head[i]; j != -1; j = next[j]) {
fu = getfa(fa, a[to[j]].u);
fv = getfa(fa, a[to[j]].v);
if (fu == fv) {
continue;
}
memcpy(t_fa[0], fa, sizeof fa);
t_fa[0][fu] = fv;
dfs(1, j);
}
for (int j = head[i]; j != -1; j = next[j]) {
fu = getfa(fa, a[to[j]].u);
fv = getfa(fa, a[to[j]].v);
if (fu != fv) {
fa[fu] = fv;
}
}
ans = ans * t_ans % mod;
}
printf("%d\n", ans);
return 0;
}
_bzoj1016 [JSOI2008]最小生成树计数【生成树】的更多相关文章
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- 1016: [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6200 Solved: 2518[Submit][St ...
- 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)
1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...
- 【bzoj1016】[JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4863 Solved: 1973[Submit][St ...
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等 就是说如果一种方案中权值为1的边有n条 ...
- [BZOJ]1016 JSOI2008 最小生成树计数
最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...
- 【bzoj1016】 JSOI2008—最小生成树计数
http://www.lydsy.com/JudgeOnline/problem.php?id=1016 (题目链接) 题意 求图的最小生成树计数. Solution %了下题解,发现要写矩阵树,15 ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...
随机推荐
- linux的bc命令介绍
bc命令是一种支持任意精度的交互执行的计算器语言.bash内置了对整数四则运算的支持,但是并不支持浮点运算,而bc命令可以很方便的进行浮点运算,当然整数运算也不再话下. 算术操作高级运算bc命令它可以 ...
- “约定优于配置”与Magento改造尝试四之block、helper和model载入
暂定本章为这个系列最后一章,还是继续沿用模块的别名(alias)概念 <modules> <Mage_Wishlist> <version>1.6.0.0</ ...
- 系统重装 Ghost系统的disk to image等等是什么意思
localdiskto disk to imade from imagepartitionto partition to image from imagecheckimage file disk这些是 ...
- MySQL基础笔记(一) SQL简介+数据类型
MySQL是一个关系型数据库管理系统(RDBMS),它是当前最流行的 RDBMS 之一.MySQL分为社区版和企业版,由于其体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发 ...
- Linux Shell 条件测试
1. 文件测试 -d 目录 -s 文件非空 -f 是正规文件 -w 有写权限 -r 有读权限 -x 有执行权限 -L 符号连接 -u 文件有suid位设置
- JavaScript操作符(关系操作符、相等操作符和条件操作符)
关系操作符用于对两个值进行比较,返回一个布尔值.关系操作符包括大于(>),小于(<),大于等于(>=),小于等于(<=).当关系操作符用于非数值时,也要先进行数值的转换.如 v ...
- 用bis和bic实现位级操作
20世纪70年代末至80年代末,DigitalEquipment的VAX计算机是一种非常流行的机型.它没有布尔运算AND和OR指令,仅仅有bis(位设置)和bic(位清除)这两种指令.两种指令的输入都 ...
- golang中获取字符串长度的几种方法
一.获取字符串长度的几种方法 - 使用 bytes.Count() 统计 - 使用 strings.Count() 统计 - 将字符串转换为 []rune 后调用 len 函数进行统计 ...
- Expression Blend实例中文教程(11) - 视觉管理器快速入门Visual State Manager(VSM)
Expression Blend实例中文教程(11) - 视觉管理器快速入门Visual State Manager(V 时间:2010-04-12 16:06来源:SilverlightChina. ...
- myeclipse 8.6安装SVN插件
方法二: 安装subclipse, SVN 插件 1.从官网下载site-1.6.9.zip文件,网址是:subclipse.tigris.org, 2.从中解压出features与plug ...