【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
最小生成树计数
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,000。数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过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
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define MSi(a) memset(a,0x3f,sizeof(a))
#define inf 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1|1
typedef pair<int,int> PII;
#define A first
#define B second
#define MK make_pair
template<typename T>
void read1(T &m)
{
T x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
if(a>) out(a/);
putchar(a%+'');
}
const int mod = ;
const int N = ;
const int M = ;
struct edge{int u,v,w;}e[M];
bool cmp(const edge& a,const edge& b){return a.w < b.w;}
struct data{int l,r,s;}d[M];
int f[N],sum;
int Find(int a)
{
return a == f[a] ?f[a]:Find(f[a]);// **
}
void dfs(int x,int now,int p)
{
if(now == d[x].r+){
if(p == d[x].s) sum++;
return ;
}
int fu = Find(e[now].u), fv = Find(e[now].v);
if(fu != fv){
f[fu] = fv;
dfs(x,now+,p+);
f[fu] = fu;
}
dfs(x,now+,p);
}
int main()
{
int n,m;
read2(n,m);
rep1(i,,m) read3(e[i].u,e[i].v,e[i].w);
sort(e+, e++m,cmp);
int cnt = ,tot = ;
rep1(i,,n) f[i] = i;
rep1(i,,m){
if(e[i].w != e[i - ].w){
d[cnt].r = i - ;
d[++cnt].l = i;
}
int fu = Find(e[i].u), fv = Find(e[i].v);
if(fu != fv){
f[fu] = fv;
tot++;
d[cnt].s++;// 边权相同的边的个数
}
}
d[cnt].r = m;
if(tot != n - )return puts(""),;//判断图是否连通
rep1(i,,n) f[i] = i;
int ans = ;
rep1(i,,cnt){
sum = ;
dfs(i,d[i].l,);
ans = ans*sum%mod;
rep1(j,d[i].l,d[i].r){
int u = e[j].u, v = e[j].v;
int fu = Find(u), fv = Find(v);
if(fu != fv) f[fu] = fv;
}
}
cout<<ans;
return ;
}
【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集的更多相关文章
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】
题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...
- [BZOJ]1016 JSOI2008 最小生成树计数
最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...
- BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)
题目链接 最小生成树有两个性质: 1.在不同的MST中某种权值的边出现的次数是一定的. 2.在不同的MST中,连接完某种权值的边后,形成的连通块的状态是一样的. \(Solution1\) 由这两个性 ...
- bzoj 1016: [JSOI2008]最小生成树计数【dfs+克鲁斯卡尔】
有一个性质就是组成最小生成树总边权值的若干边权总是相等的 这意味着按边权排序后在权值相同的一段区间内的边能被选入最小生成树的条数是固定的 所以先随便求一个最小生成树,把每段的入选边数记录下来 然后对于 ...
- bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 就是缩点,每次相同权值的边构成的联通块求一下matrix tree.注意gauss里的 ...
- BZOJ 1016 [JSOI2008]最小生成树计数 ——Matrix-Tree定理
考虑从小往大加边,然后把所有联通块的生成树个数计算出来. 然后把他们缩成一个点,继续添加下一组. 最后乘法原理即可. 写起来很恶心 #include <queue> #include &l ...
- 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)
1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...
- 1016: [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6200 Solved: 2518[Submit][St ...
随机推荐
- java_IO读写模版
InputStream in = null; OutputStream out = null; try{ in = new FileInputStream(); int len=0; byte buf ...
- 使用Vert.x构建Web服务器和消息系统
如果你对Node.js感兴趣,Vert.x可能是你的下一个大事件:一个建立在JVM上一个类似的架构企业制度. 这一部分介绍Vert.x是通过两个动手的例子(基于Vert.x 2.0). 当Node.j ...
- swift 如何使用OC中宏的功能
swift中没有宏的概念,那么我们在swift使用宏的功能来提高效率呢? 一.使用关键字 let 来声明一个常量 存储相应的值,以下代码声明了常量 myColor 来存储一种指定的颜色 let my ...
- 可扩展的listview--Expandablelistview
layout.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" x ...
- iOS-label出现未知边框线的bug
在前段时间碰到了一个问题 label上出现了一个位置的右边框 仔细查看代码发现没有指定边框 而且奇怪的是只显示右边框 其他边框没有显示 需求效果图: 实际效果图: 结构图: 通过查看结构图 可 ...
- 使用Log4Net发送日志邮件 (转载)
前言 公司前几天重新确立了考核指标,主要是针对我们研发部,而我们的经理要求也高,对我们绩效考核扣分也挺狠的,100分的,出了几个严重bug就变 0分,反正只要被用户发现并且提出来了,就会扣分,没被用户 ...
- ListView的item中有button和checkbox,listview的点击事件无效
ListView的item中有button和checkbox,listview的点击事件无效,解决办法: 在item布局文件中的根控件中添加属性设置: android:descendantFocusa ...
- zabbix的邮件报警
邮件报警插件 #!/usr/bin/python #coding:utf-8 import smtplib from email.MIMEText import MIMEText import os ...
- Java Thread interrupt
现有线程对象threadA,调用threadA.interrupt(),则threadA中interrupted状态会被置成false,很多线程中都是通过isInterrupted()方法来检测线程是 ...
- C#中var类型
var关键字是C#3.0新增的特性,当你不能确定自己需要使用的类型时,可以选择使用var var可以代替任何类型,var关键字指示编译器根据初始化语句右侧表达式推断变量类型 例: int a = 2 ...