【题目链接】

点击打开链接

【算法】

笔者做这题参考了这篇博客 :

https://blog.sengxian.com/solutions/bzoj-1016

推荐阅读

首先,我们需要知道三个定理 :

定理1 : 若A,B是两棵不同的最小生成树,它们的权值从小到大排列分别为 :

                        W(a1),W(a2),W(a3)....W(an-1)

                        W(b1),W(b2),W(b3)....W(bn-1)

                        那么,对于任意的i,都有W(ai) = W(bi)

          定理2 : 当最小生成树中所有w <= w0的边被加入后,图的联通性唯一

          定理3 : 若A是一棵最小生成树,A中权值为v的边有k条,那么,用任意k条权值为v的边替换A中权值为v的边且不产生

                        环的方案都是一棵最小生成树

         证明详见笔者推荐的那篇博客

有了这三个定理,这题就很好做啦! 首先,任意求一棵最小生成树,记录每种权值的边出现的次数,然后,对每种

权值的边做一遍深度优先搜索DFS,求出方案数,然后乘法原理,即可

【代码】

注意因为进行DFS时需要回溯,所以,并查集不能路径压缩

#include<bits/stdc++.h>
using namespace std;
#define MAXN 110
#define MAXM 1010
const int MOD = ; int n,m,i,j,ans = ,pos,len,sum,sx,sy;
int fa[MAXN],s[MAXN],val[MAXN],l[MAXN],r[MAXN]; struct Edge
{
int u,v,w;
} e[MAXM];
inline void init(int n)
{
int i;
for (i = ; i <= n; i++) fa[i] = i;
}
int get_root(int x)
{
if (fa[x] == x) return x;
return get_root(fa[x]);
} bool cmp(Edge a,Edge b)
{
return a.w < b.w;
}
bool kruskal()
{
int i,cnt = ,sx,sy;
for (i = ; i <= m; i++)
{
sx = get_root(e[i].u);
sy = get_root(e[i].v);
if (e[i].w == val[len]) r[len]++;
if (sx != sy)
{
fa[sx] = sy;
cnt++;
if (e[i].w == val[len]) s[len]++;
else
{
len++;
l[len] = r[len] = i;
s[len]++;
val[len] = e[i].w;
}
}
}
return cnt == n - ;
}
inline void dfs(int now,int r,int c)
{
int sx,sy;
if (now > r)
{
if (c == s[pos]) sum++;
return;
}
dfs(now+,r,c);
sx = get_root(e[now].u);
sy = get_root(e[now].v);
if (sx != sy)
{
fa[sx] = sy;
dfs(now+,r,c+);
fa[sx] = sx;
}
} int main() { scanf("%d%d",&n,&m);
for (i = ; i <= m; i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
sort(e+,e+m+,cmp);
init(n);
if (!kruskal())
{
puts("");
return ;
}
init(n);
for (i = ; i <= len; i++)
{
sum = ;
pos = i;
dfs(l[i],r[i],);
ans = (ans * sum) % MOD;
for (j = l[i]; j <= r[i]; j++)
{
sx = get_root(e[j].u);
sy = get_root(e[j].v);
if (sx != sy) fa[sx] = sy;
}
}
printf("%d\n",ans); return ; }

【JSOI 2008】 最小生成树计数的更多相关文章

  1. JSOI 2008 最小生成树计数

    JSOI 2008 最小生成树计数 今天的题目终于良心一点辣 一个套路+模版题. 考虑昨天讲的那几个结论,我们有当我们只保留最小生成树中权值不超过 $ k $ 的边的时候形成的联通块是一定的. 我们可 ...

  2. BZOJ 1016 JSOI 2008 最小生成树计数 Kruskal+搜索

    题目大意:给出一些边,求出一共能形成多少个最小生成树. 思路:最小生成树有非常多定理啊,我也不是非常明确.这里仅仅简单讲讲做法.关于定各种定理请看这里:http://blog.csdn.net/wyf ...

  3. 最小生成树计数 bzoj 1016

    最小生成树计数 (1s 128M) award [问题描述] 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一 ...

  4. 【bzoj1016】 JSOI2008—最小生成树计数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1016 (题目链接) 题意 求图的最小生成树计数. Solution %了下题解,发现要写矩阵树,15 ...

  5. [BZOJ]1016 JSOI2008 最小生成树计数

    最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...

  6. bzoj1016 [JSOI2008]最小生成树计数

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3517  Solved: 1396[Submit][St ...

  7. 【BZOJ】【1016】【JSOI2008】最小生成树计数

    Kruskal/并查集+枚举 唉我还是too naive,orz Hzwer 一开始我是想:最小生成树删掉一条边,再加上一条边仍是最小生成树,那么这两条边权值必须相等,但我也可以去掉两条权值为1和3的 ...

  8. 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集

    最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...

  9. BZOJ_1016_[JSOI2008]_最小生成树计数_(dfs+乘法原理)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1016 给出一张图,其中具有相同权值的边的数目不超过10,求最小生成树的个数. 分析 生成树的计 ...

  10. BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )

    不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...

随机推荐

  1. [Python3网络爬虫开发实战] 2.3-爬虫的基本原理

    我们可以把互联网比作一张大网,而爬虫(即网络爬虫)便是在网上爬行的蜘蛛.把网的节点比作一个个网页,爬虫爬到这就相当于访问了该页面,获取了其信息.可以把节点间的连线比作网页与网页之间的链接关系,这样蜘蛛 ...

  2. C#基础学习(二)

    ---恢复内容开始--- 面向对象 (类是不占内存,实例占内存) C#与python不用可以直接从另一个文件直接实例化一个类,不需要导包:                                ...

  3. linux命令 dig-域名查询工具

    博主推荐:更多网络测试相关命令关注 网络测试  收藏linux命令大全 dig命令是常用的域名查询工具,可以用来测试域名系统工作是否正常. 语法 dig(选项)(参数) 选项 @<服务器地址&g ...

  4. Python之数字

    Python之数字 int(数字)===>在Python3中,int没有范围,在Python2中,int超出范围就叫长整型(Long). 浮点运算:单精度 float 双精度 double a: ...

  5. C++迭代器之'插入迭代器

    1. 定义 插入型迭代器(Insert Iterator),又叫插入器(Inserter). 2. 作用 插入迭代器的主要功能为把一个赋值操作转换为把相应的值插入容器的操作.算法库对所有在容器上的操作 ...

  6. pcb中几个层的解释

    阻焊层(Solder Mask):又称为绿油层,是PCB的非布线层,用于制成丝网漏印板,将不需要焊接的地方涂一层阻焊物质,防止焊接PCB时焊锡在高温下的流动性.在阻焊层上预留的焊盘大小,要比实际焊盘大 ...

  7. clip-path实现loading圆饼旋转效果以及其他方法

    一.loading效果 二.clip-path css中的剪切clip-path属性是CSS Masking模块的一部分. 矩形 clip-path:inset(top right bottom le ...

  8. C51 使用端口 个人笔记

    使用整个端口的8个引脚: 八个引脚,需要8位2进制,2位十六进制 #define P0 led led = 0x3f; //led = ~0x3f; 使用某个端口的某一个引脚 sbit led = P ...

  9. 管理Cookie和Session

    管理Cookie和Session 前言 这几天中,一直再跟漏洞打交道,而在这些漏洞中,出现的最多的就是 Cookie 和 Session 了.这篇文章就简单的介绍一些 Cookie 中最常用的四个属性 ...

  10. [NOIP2008] 提高组 洛谷P1125 笨小猴

    题目描述 笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼.但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大! 这种方法的具体描述如下:假设maxn是单词中出现次数最 ...