最小生成树计数

【问题描述】

现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方案数对31011的模就可以了。

【输入格式】

第一行包含两个数,n和m,其中1<=n<=100; 1<=m<=1000; 表示该无向图的节点数和边数。每个节点用1~n的整数编号。接下来的m行,每行包含两个整数:a, b, c,表示节点a, b之间的边的权值为c,其中1<=c<=1,000,000,000。数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过10条。

【输出格式】

输出不同的最小生成树有多少个。你只需要输出数量对31011的模就可以了。

【样例输入】

4 6

1 2 1

1 3 1

1 4 1

2 3 2

2 4 1

3 4 1

【样例输出】

8


题解:

1.用克鲁斯卡尔求一遍最小生成树,统计出某一权值在最小生成树中的个数(即所有权值相同的边的个数)

2.考虑对于每一种权值的方案(Dfs)

要求:

(1)选出的边数等于最小生成树中该权值拥有的边数

原理:最小生成树中每种权值的边数不变

(2)不含环,判断是否有环可以用不压缩路径的并查集处理

原理:树中不含环

3.将所有权值的方案相乘

原理:在最小生成树中对于每一种权值的合法方案构建出的图的连通情况相同

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
inline int Get()
{
int x = , s = ;
char c = getchar();
while('' > c || c > '')
{
if(c == '-') s = -;
c = getchar();
}
while('' <= c && c <= '')
{
x = (x << ) + (x << ) + c - '';
c = getchar();
}
return x * s;
}
struct shape
{
int x, y, z;
};
shape a[];
int n, m, k;
int tot;
int cnt;
int sum;
int l[];
int r[];
int s[];
int fat[];
int c[];
int u[];
inline bool rule(shape a, shape b)
{
return a.z < b.z;
}
int Find(int x)
{
while(fat[x] != x) x = fat[x];
return x;
}
void Dfs(int fig, int va, int le)
{
if(fig == s[va])
{
sum = (sum + ) % ;
if(sum == )
for(int i = ; i <= c[]; ++i)
u[i] = c[i];
// for(int i = 1; i <= c[0]; ++i) printf("%d ", c[i]);
// cout<<endl;
return;
}
for(int i = le; i <= r[va]; ++i)
{
int x = Find(a[i].x);
int y = Find(a[i].y);
int cx = fat[x];
if(x == y) continue;
fat[x] = y;
c[++c[]] = i;
Dfs(fig + , va, i + );
fat[x] = cx;
--c[];
}
}
int main()
{
n = Get(), m = Get();
for(int i = ; i <= m; ++i)
{
a[i].x = Get();
a[i].y = Get();
a[i].z = Get();
}
sort(a + , a + + m, rule);
for(int i = ; i <= n; ++i) fat[i] = i;
for(int i = ; i <= m; ++i)
{
if(a[i].z != a[i - ].z)
{
r[tot] = i - ;
++tot;
l[tot] = i;
}
if(k != n - )
{
int x = Find(a[i].x), y = Find(a[i].y);
if(x != y)
{
fat[x] = y;
++s[tot];
++k;
}
}
}
if(k != n - )
{
printf("");
return ;
}
r[tot] = m;
for(int i = ; i <= n; ++i) fat[i] = i;
int ans = ;
for(int i = ; i <= tot; ++i)
if(s[i])
{
sum = ;
Dfs(, i, l[i]);
for(int l = ; l <= u[]; ++l)
{
int x = Find(a[u[l]].x);
int y = Find(a[u[l]].y);
fat[x] = y;
}
ans = (ans * sum) % ;
}
printf("%d", ans);
}

最小生成树计数 bzoj 1016的更多相关文章

  1. 最小生成树的边的概念问题!!! 最小生成树的计数 bzoj 1016

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

  2. 1016: [JSOI2008]最小生成树计数 - BZOJ

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

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

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

  4. [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】

    题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...

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

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

  6. 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)

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

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

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

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

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

  9. 1016: [JSOI2008]最小生成树计数

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

随机推荐

  1. [原] KVM 虚拟化原理探究 —— 目录

    KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...

  2. duang~免费的学习视频来啦:学霸君之全栈测试

    学霸君向童鞋们推荐一款 同名学霸学习 视频教程 重点是完全免费收看学习噢!!! 今天 学霸君推荐腾讯课堂的学霸君之全栈测试 复制下方链接至腾讯课堂中报名学习 https://ke.qq.com/cou ...

  3. C#使用GET、POST请求获取结果

    C#使用GET.POST请求获取结果,这里以一个简单的用户登陆为例. 1. 使用GET请求获取结果 1.1 创建LoginHandler.aspx处理页面 protected void Page_Lo ...

  4. js 入门级常见问题

    写在前面:以下是个人总结的关于js常见的入门级的问题一些总结. js是有 ECMAScript Dom Bom 三部分组成. 1,undefined,NaN,Null,infinity 1) unde ...

  5. (转载) RESTful API 设计指南

    作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...

  6. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  7. json

    #json序列化,只能处理简单的数据类型,如:字典.列表.字符串,类和函数等数据类型过于复杂,不支持序列化import jsondef sayhi(name): print('hello,', nam ...

  8. 我的MYSQL学习心得(四) 数据类型

    我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(五) 运 ...

  9. ASP.NET Core 在 JSON 文件中配置依赖注入

    前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ...

  10. [DeviceOne开发]-do_LinearLayout组件使用技巧

    一.摘要 今天跟大家主要来介绍一下DeviceOne中的do_linearlayout这个布局,在DeviceOne开发中,do_linearlayout这个布局是相当重要. 现在给大家来总结一下. ...