【bzoj1016】[JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 4863 Solved: 1973
[Submit][Status][Discuss]
Description
现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的
最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生
成树可能很多,所以你只需要输出方案数对31011的模就可以了。
Input
第一行包含两个数,n和m,其中1<=n<=100; 1<=m<=1000; 表示该无向图的节点数和边数。每个节点用1~n的整
数编号。接下来的m行,每行包含两个整数:a, b, c,表示节点a, b之间的边的权值为c,其中1<=c<=1,000,000,0
00。数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过10条。
Output
输出不同的最小生成树有多少个。你只需要输出数量对31011的模就可以了。
Sample Input
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1
Sample Output
就是不同的最小生成树方案,每种权值的边的数量是确定的,每种权值的边的作用是确定的
排序以后先做一遍最小生成树,得出每种权值的边使用的数量x
然后对于每一种权值的边搜索,得出每一种权值的边选择方案
然后乘法原理
转自——hzwer.com
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<ctime>
using namespace std;
#define mod 31011
int n,m,len,sum,tot,ans=,f[];
struct node{int x,y,v;}e[];
struct sha{int l,r,v;}a[];
bool cmp(node a,node b) {return a.v<b.v;}
int find(int x) {return f[x]==x?x:find(f[x]);}
namespace INIT
{
char buf[<<],*fs,*ft;
inline char getc() {return (fs==ft&&(ft=(fs=buf)+fread(buf,,<<,stdin),fs==ft))?:*fs++;}
inline int read()
{
int x=,f=; char ch=getc();
while(!isdigit(ch)) {if(ch=='-') f=-; ch=getc();}
while(isdigit(ch)) {x=x*+ch-''; ch=getc();}
return x*f;
}
}using namespace INIT;
void dfs(int x,int now,int k)
{
if(now==a[x].r+)
{
if(k==a[x].v) sum++;
return;
}
int p=find(e[now].x),q=find(e[now].y);
if(p!=q)
{
f[p]=q;
dfs(x,now+,k+);
f[p]=p; f[q]=q;
}
dfs(x,now+,k);
}
int main()
{
//freopen("cin.in","r",stdin);
//freopen("cout.out","w",stdout);
n=read(); m=read();
for(int i=;i<=n;i++) f[i]=i;
for(int i=;i<=m;i++) e[i].x=read(),e[i].y=read(),e[i].v=read();
sort(e+,e+m+,cmp);
for(int i=;i<=m;i++)
{
if(e[i].v!=e[i-].v) {a[++len].l=i;a[len-].r=i-;}
int p=find(e[i].x),q=find(e[i].y);
if(p!=q) {f[p]=q; a[len].v++; tot++;}
}
a[len].r=m;
if(tot!=n-) {printf("0\n"); return ;}
for(int i=;i<=n;i++) f[i]=i;
for(int i=;i<=len;i++)
{
sum=;
dfs(i,a[i].l,);
ans=(ans*sum)%mod;
for(int j=a[i].l;j<=a[i].r;j++)
{
int p=find(e[j].x),q=find(e[j].y);
if(p!=q) f[p]=q;
}
}
printf("%d\n",ans);
return ;
}
【bzoj1016】[JSOI2008]最小生成树计数的更多相关文章
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等 就是说如果一种方案中权值为1的边有n条 ...
- BZOJ1016:[JSOI2008]最小生成树计数(最小生成树,DFS)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- 【Matrix-tree定理】【并查集】【kruscal算法】bzoj1016 [JSOI2008]最小生成树计数
题意:求一个图的最小生成树个数. 矩阵树定理:一张无向图的生成树个数 = (度数矩阵 - 邻接矩阵)的任意一个n-1主子式的值. 度数矩阵除了对角线上D[i][i]为i的度数(不计自环)外,其他位置是 ...
- [BZOJ1016][JSOI2008]最小生成树计数(结论题)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1016 分析: 首先有个性质:如果边集E.E'都可以表示一个图G的最小生成树(当然E和E ...
- [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- 【最小生成树】BZOJ1016: [JSOI2008]最小生成树计数
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- 2018.09.24 bzoj1016: [JSOI2008]最小生成树计数(并查集+搜索)
传送门 正解是并查集+矩阵树定理. 但由于数据范围小搜索也可以过. 我们需要知道最小生成树的两个性质: 不同的最小生成树中,每种权值的边出现的个数是确定的 不同的生成树中,某一种权值的边连接完成后,形 ...
- [BZOJ1016][JSOI2008]最小生成树计数 最小生成树 搜索
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 做这道题之前需要知道一些结论,同一个图的最小生成树中相同权值的边的个数是不会变的,如 ...
随机推荐
- Java一般要学多久?
其实学java一般要多久?因人而异,有些人资质好,头脑聪明几个月就能学会,有些人天生愚钝,理解能力差,不过勤能补拙,只是时间相对长点 要坚持住.不过java相对于C,C++java而言,java无疑简 ...
- ArcGIS图例标注上标和下标
1. 插入图例 在布局视图下,从插入中选择"图例",我们获得以下的样式: 2. 转为单个图形 选择图例,点击右键,选择"转化为图形",再次点击右键,点击&quo ...
- 微信小程序-富文本解析插件wxParse基础使用及问题解决
一.插件准备 在github上可以直接下载该插件:https://github.com/icindy/wxParse 二.基本使用 1.将插件导入项目: 将wxParse文件夹放在项目目录下,如图: ...
- [转]MFC 调用 printf 输出
摘自:http://blog.csdn.net/miyunhong/article/details/6704121 #include <io.h> #include <fcntl.h ...
- PTA L3-023 计算图 (dfs+数学推导)
“计算图”(computational graph)是现代深度学习系统的基础执行引擎,提供了一种表示任意数学表达式的方法,例如用有向无环图表示的神经网络. 图中的节点表示基本操作或输入变量,边表示节点 ...
- latch的产生和消除
一直都知道fpga中有latch这么一回事,但是一直都不太清楚到底什么是锁存器,它是怎么产生的,它到底和寄存器有多少区别,它怎么消除.为什么说他不好? 一,是什么 锁存器是一种在异步时序电路系统中,对 ...
- yii 操作cookie
原文地址:http://blog.sina.com.cn/s/blog_664c9f650100yqkn.html 设置cookie: $cookie = new CHttpCookie('mycoo ...
- Oracle Stream配置详细步骤
1 引言 Oracle Stream功能是为提高数据库的高可用性而设计的,在Oracle 9i及之前的版本这个功能被称为Advance Replication.Oracle Stream利用高级队列技 ...
- Eclipse自动生成 get/set
步骤一:在声明的数据域中按Ctrl+1: 步骤二:点击最后一个选项Create getter and setter,在弹出的对话框中点击确定: 在介绍另外一个方法: 步骤一:声明完类的数据域之后,输入 ...
- linux下PS1命令提示符设置
linux下PS1命令提示符设置 在此文件最后一行添加:vim /etc/profileexport PS1='[\u@\h \W]\$ ' #这里必须用单引号. \d :代表日期,格式为 ...