大视野 1016: [JSOI2008]最小生成树计数(最小生成树)
总结:此类题需要耐心观察规律,大胆猜想,然后证明猜想,得到有用的性质,然后解答。 简单的说:找隐含性质。
传送门:http://61.187.179.132/JudgeOnline/problem.php?id=1016
题意:n个点m条边的图,问其最小生成树的个数(只要有一条边不同,就算不同)。n<100, m<1000 权值c < 10^9, 其中权相同的边的数量不会超过10条。
思路:
经过观察思考,得到以下结论:
任意两个最小生成树,将其所有边的边长排序后,将得到完全相同的结果。
意思是:只能用相同长度的边来代替,借此得到不同的最小生成树。
又因为每种权相同的边数不超过10,则可以用以下方法:
首先,生成一个最小生成树,得到其包含的所有权值以及数量。
其次,将其中某种权值的边删除,然后在图中取出所有权值相同的边, 状态压缩暴力匹配。得到这种边可以组合的方案数。
将所有权值的边的方案数相乘,就得到答案。
时间复杂度:MlogM + n(2^10*n) + M
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mod 31011
#define N 200 struct Edge{
int a, b, c;
bool operator < (const Edge &b) const {
return c < b.c;
}
}e[], mintre[]; struct BCJ{
int fa[N];
void init(int n) {
for (int i = ; i <= n; i++) {
fa[i] = i;
}
}
int find(int u) {
return fa[u]== u ? fa[u] : fa[u] = find(fa[u]);
}
void unin(int u, int v) {
fa[find(v)] = find(u);
}
}b; int main() {
int n, m;
while (scanf("%d%d", &n, &m) != EOF) {
for (int i = ; i < m; i++) {
scanf("%d%d%d", &e[i].a, &e[i].b, &e[i].c);
}
sort(e, e+m);
int top = ;
b.init(n);
for (int i = ; i < m; i++) {
if (b.find(e[i].a) != b.find(e[i].b)) {
b.unin(e[i].a, e[i].b);
mintre[top++] = e[i];
}
}
if (top != n-) {
puts("");
continue;
} int minp = ;
int ep = ;
int ans = ;
while (true) {
if (minp == top || ep == m) break;
int nowc = mintre[minp].c;
//printf("nowc = %d\n", nowc);
BCJ nowTong;
nowTong.init(n);
for (int i = ; i < top; i++) {
if (mintre[i].c != nowc) {
nowTong.unin(mintre[i].a, mintre[i].b);
}
} int edgeNum = ;
while (ep < m && e[ep].c < nowc) ep++;
while (ep < m && e[ep].c == nowc) {
edgeNum++;
ep++;
} int nownum = ;
while (minp < top && mintre[minp].c == nowc) {
nownum++;
minp++;
}
if (edgeNum == nownum) continue;
int end = (<<edgeNum);
int nowans = ;
BCJ tmpTong;
for (int i = ; i < end; i++) {
int tmpi = i;
int num = ;
while (tmpi) {
num += (tmpi&);
tmpi>>=;
}
if (num != nownum) continue; tmpTong = nowTong;
tmpi = i;
int unintime = ;
for (int j = ep-; e[j].c == nowc; j--) {
if (tmpi&) {
if (tmpTong.find(e[j].a) != tmpTong.find(e[j].b)) {
unintime++;
tmpTong.unin(e[j].a, e[j].b);
}
}
tmpi>>=;
}
if (unintime == nownum) {
nowans++;
}
}
ans *= nowans;
ans %= mod;
}
printf("%d\n", ans);
}
return ;
}
大视野 1016: [JSOI2008]最小生成树计数(最小生成树)的更多相关文章
- BZOJ1016:[JSOI2008]最小生成树计数(最小生成树,DFS)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- [BZOJ1016][JSOI2008]最小生成树计数 最小生成树 搜索
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 做这道题之前需要知道一些结论,同一个图的最小生成树中相同权值的边的个数是不会变的,如 ...
- 【BZOJ1016】【Luogu P4208】 [JSOI2008]最小生成树计数 最小生成树,矩阵树定理
蛮不错的一道题,遗憾就遗憾在数据范围会导致暴力轻松跑过. 最小生成树的两个性质: 不同的最小生成树,相同权值使用的边数一定相同. 不同的最小生成树,将其都去掉同一个权值的所有边,其连通性一致. 这样我 ...
- $bzoj1016-JSOI2008$ 最小生成树计数 最小生成树 $dfs/matrix-tree$定理
题面描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的).由于不同的 ...
- BZOJ1016最小生成树计数 最小生成树 + 排列组合
@[最小生成樹, 排列組合] Discription 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的 最小生成树.(如果两颗最小生成树中至少有一条边不 ...
- 大视野 1012: [JSOI2008]最大数maxnumber(线段树/ 树状数组/ 单调队列/ 单调栈/ rmq)
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 9851 Solved: 4318[Submi ...
- 【BZOJ】【1016】【JSOI2008】最小生成树计数
Kruskal/并查集+枚举 唉我还是too naive,orz Hzwer 一开始我是想:最小生成树删掉一条边,再加上一条边仍是最小生成树,那么这两条边权值必须相等,但我也可以去掉两条权值为1和3的 ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- 1016: [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6200 Solved: 2518[Submit][St ...
随机推荐
- Python学习笔记5(函数)
[摘要]本文详细介绍python中的函数,以及与之相关的参数和作用域的概念,并介绍递归的概念以及在程序中的应用. 函数定义 定义函数要用函数定义语句def.如下: def hello(name): r ...
- 科技庄园(背包dp)---对于蒟蒻来说死了一大片的奇题
题目描述: Life种了一块田,里面种了一些桃树. Life对PFT说:“我给你一定的时间去摘桃,你必须在规定的时间之内回到我面前,否则你摘的桃都要归我吃!” PFT思考了一会,最终答应了! 由于PF ...
- APP客户端图片上传PHP接口
1.客户端 file_get_contents($_FILES['img']['tmp_name']) //获取临时目录下的上传文件流,加密传给接口 2.接口处理端 $img = file_get ...
- SQL Server ALwayson 正在解析
原因:把主库切换到辅助副本以后,集群全部出现正在解析的情况,数据库显示“恢复挂起” 过程:把服务器重启,原以为正在解析会恢复正常.结果失败. 解决方法:出现“正在解析”的情况跟故障转移群集有关,进故障 ...
- Python学习笔记:PyInstaller(exe程序打包)
PyInstaller可以将Python程序打包成一个exe程序来独立运行,用户使用时只需要执行这个exe文件即可,不需要在机器上再安装Python及其他包就可运行了.另外,PyInstaller相较 ...
- LA 4094 WonderTeam 构造
题意: 一共有\(n\)支队伍参加比赛,每两支队伍比赛两场,主客场各一场. 胜场得\(3\)分,平局得1分,败场不得分. 一支得分为\(p\)的队伍的排名\(=\)分数大于\(p\)的队伍数\(+1\ ...
- MySQL主从复制(Master-Slave)
MySQL数据库自身提供的主从复制功能可以方便的实现数据的多处自动备份,实现数据库的拓展.多个数据备份不仅可以加强数据的安全性,通过实现读写分离还能进一步提升数据库的负载性能. 下图就描述了一个多个数 ...
- TCP缓冲区大小及限制
这个问题在前面有的部分已经涉及,这里在重新总结下.主要参考UNIX网络编程. (1)数据报大小IPv4的数据报最大大小是65535字节,包括IPv4首部.因为首部中说明大小的字段为16位.IPv6的数 ...
- webservice soap wsdl简介
先给出一个概念 SOA ,即Service Oriented Architecture ,中文一般理解为面向服务的架构, 既然说是一种架构的话,所以一般认为 SOA 是包含了运行环境,编程模型, 架构 ...
- Linux inode 之我见
Linux硬盘组织方式为:引导区.超级块(superblock),索引结点(inode),数据块(datablock),目录块(diredtory block).其中超级块中包含了关于该硬盘或分区上的 ...