最小生成树计数

【问题描述】

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

    本文使用FFmpeg + SoundTouch实现将音频解码后,进行变调变速处理,并将处理后的结果保存为WAV文件. 主要有以下内容: 实现一个FFmpeg的工具类,保存多媒体文件所需的解码信息 将解 ...

  2. background例子

  3. iOS 原生地图地理编码与反地理编码

    当我们要在App实现功能:输入地名,编码为经纬度,实现导航功能. 那么,我需要用到原生地图中的地理编码功能,而在Core Location中主要包含了定位.地理编码(包括反编码)功能. 在文件中导入 ...

  4. mysql数据库主从同步

    环境: Mater:   CentOS7.1  5.5.52-MariaDB  192.168.108.133 Slave:   CentOS7.1  5.5.52-MariaDB  192.168. ...

  5. 萌新笔记——linux下查看内存的使用情况

    windows上有各种软件可以进行"一键加速"之类的操作,释放掉一些内存(虽然我暂时不知道是怎么办到的,有待后续学习).而任务管理器也可以很方便地查看各进程使用的内存情况,如下图: ...

  6. 【腾讯Bugly干货分享】聊聊苹果的Bug - iOS 10 nano_free Crash

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/hnwj24xqrtOhcjEt_TaQ9w 作者:张 ...

  7. 【Knockout.js 学习体验之旅】(3)模板绑定

    本文是[Knockout.js 学习体验之旅]系列文章的第3篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...

  8. [C#版本]有趣啊!各种编程语言实现 2 + 2 = 5

    首页新闻里面那个 [新闻头条]有趣啊!各种编程语言实现 2 + 2 = 5 其他的就不评论的,但是其中C#版的 真是逗比啊...评论中各种吐槽有木有... static void Main (stri ...

  9. python处理命令行参数

    直接从命令行执行py文件的时候如果带有参数,如何获取这些参数,如何解析? http://blog.chinaunix.net/uid-20786165-id-3182268.html sys.argv ...

  10. iOS开发的知名大牛博客小汇

    王巍的博客:王巍目前在日本横滨任职于LINE.工作内容主要进行Unity3D开发,8小时之外经常进行iOS/Mac开发.他的陈列柜中已有多款应用,其中番茄工作法工具非常棒.http://onevcat ...