最小生成树计数

【问题描述】

现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方案数对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. AutoMapper的介绍与使用(一)

    软件环境 vs2015 asp.net mvc 5 .NET Framework 4.5.2 AutoMapper 5.2.0.0 AutoMapper安装 新建asp.net mvc 项目 Auto ...

  2. UML图中经常用到几种的关系图例

    学习这个东西挺奇怪的,时间一长就容易忘记,或者记不清楚.今天看到一些UML图的关系,发现有些出入了,索性就写下来,以后再忘记的时候过来看看. 在UML的类图中,常见的有以下几种关系: 继承(Gener ...

  3. Highcharts中国地图热力图

    最近有个项目需要将MC销量按大陆各省统计,并以中国地图人力图效果显示.由于项目一直使用Highcharts进行图表的统计,故采用Highmaps来实现. 效果如下: 1)中国各个省.直辖市.自治区: ...

  4. Oracle第一步

    Oracle 启动数据库 Startup [NOMOUNT|MOUNT|OPEN|FORCE] [restrict] [pfile=filename] 启动实例,加载数据库,启动数据库 oRACLE关 ...

  5. jQuery radio的取值与赋值

    取值: $("input[name='radioName']:checked").val(); 赋值: $("input[name='radioName'][value= ...

  6. Linux实战教学笔记02:计算机系统硬件核心知识

    标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 互联网企业常见服务器介绍 1.1 互联网公司服务器品牌 - DELL(大多数公司,常用) - HP - IBM(百度在用) 浪潮 联想 航天联 ...

  7. hibernate5.2需要的最少jar文件

    hibernate5.2需要的最少jar文件: required文件夹中的所有jar文件 + mysql-connector-java-bin.jar.

  8. 《Note --- Unreal --- MemPro (CONTINUE... ...)》

    Mem pro 是一个主要集成内存泄露检测的工具,其具有自身的源码和GUI,在GUI中利用"Launch" button进行加载自己待检测的application,目前支持的平台为 ...

  9. Ubuntu下利用Mono,Jexus搭建Asp.Net(MVC) Web服务器

    最近在Ubuntu上搭建了Asp.Net的Web服务器,其中遇到很多问题,整理一下思路,以备后用. 搭建环境以及配套软件 Ubuntu: 11.10 Mono:3.0.6 下载地址(http://do ...

  10. 【Web动画】CSS3 3D 行星运转 && 浏览器渲染原理

    承接上一篇:[CSS3进阶]酷炫的3D旋转透视 . 最近入坑 Web 动画,所以把自己的学习过程记录一下分享给大家. CSS3 3D 行星运转 demo 页面请戳:Demo.(建议使用Chrome打开 ...