【BZOJ】【1016】【JSOI2008】最小生成树计数
Kruskal/并查集+枚举
唉我还是too naive,orz Hzwer
一开始我是想:最小生成树删掉一条边,再加上一条边仍是最小生成树,那么这两条边权值必须相等,但我也可以去掉两条权值为1和3的,再加上权值为2和2的,不也满足题意吗?事实上,如果这样的话……最小生成树应该是1和2,而不是1和3或2和2!!!
所以呢?所以对于一个图来说,最小生成树有几条边权为多少的边,都是固定的!所以我们可以做一遍Kruskal找出这些边权,以及每种边权出现的次数。然后,对于每种边权,比方说出现了$v_i$次,那么可以替换的一定是形成环的!且这种边权的选取方案对其他边权的没有影响,我就可以$2^{v_i}$枚举每条边是否选取,暴力找出这$v_i$条边的可行方案数,这个复杂度并不高,因为题目保证了这里的$v_i \leq 10$。
proverbs:
最小生成树的两个性质:
1、边权相等的边的个数一定。
2、做完边权为w的所有边时,图的连通性相同。
/**************************************************************
Problem: 1016
User: Tunix
Language: C++
Result: Accepted
Time:8 ms
Memory:1300 kb
****************************************************************/ //BZOJ 1016
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=,INF=~0u>>,MOD=;
typedef long long LL;
/******************tamplate*********************/
int n,m,fa[N];
struct edge{int u,v,w;}e[];
struct data{int l,r,v;}a[];
bool cmp(edge a,edge b){return a.w<b.w;}
int Find(int x){return fa[x]==x?x:Find(fa[x]);}
int sum,ans=,tot;
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].u),q=Find(e[now].v);
if (p!=q){
fa[p]=q;
dfs(x,now+,k+);
fa[p]=p; fa[q]=q;
}
dfs(x,now+,k);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1016.in","r",stdin);
freopen("1016.out","w",stdout);
#endif
n=getint(); m=getint();
F(i,,m){
e[i].u=getint(); e[i].v=getint(); e[i].w=getint();
}
sort(e+,e+m+,cmp);
int cnt=,now=;
F(i,,n) fa[i]=i;
F(i,,m){
if (i==||e[i].w!=e[i-].w) {a[++cnt].l=i;a[cnt-].r=i-;}
int p=Find(e[i].u),q=Find(e[i].v);
if (p!=q){ fa[p]=q; a[cnt].v++; tot++;}
}
a[cnt].r=m;
if (tot!=n-){puts("");return ;}
F(i,,n) fa[i]=i;
F(i,,cnt){
sum=;
dfs(i,a[i].l,);
ans=ans*sum%MOD;
F(j,a[i].l,a[i].r){
int p=Find(e[j].u),q=Find(e[j].v);
if (p!=q) fa[p]=q;
}
}
printf("%d\n",ans);
return ;
}
1016: [JSOI2008]最小生成树计数
Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 3312  Solved: 1311
[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,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
HINT
Source
【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]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)
		
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 就是缩点,每次相同权值的边构成的联通块求一下matrix tree.注意gauss里的 ...
 - bzoj 1016: [JSOI2008]最小生成树计数【dfs+克鲁斯卡尔】
		
有一个性质就是组成最小生成树总边权值的若干边权总是相等的 这意味着按边权排序后在权值相同的一段区间内的边能被选入最小生成树的条数是固定的 所以先随便求一个最小生成树,把每段的入选边数记录下来 然后对于 ...
 - 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 ...
 - 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
		
最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...
 
随机推荐
- 【转】一个高端.NET技术人才的2014年度总结
			
[转]一个高端.NET技术人才的2014年度总结 本人在一家公司做技术负责人.主要从事的是.net方面的开发与管理,偏重开发. 弹指一挥间,时间飘然而过,转眼又是一年. 回顾2014年,是我人生中最 ...
 - 基于zookeeper的远程方法调用(RMI)的实现
			
采用zookeeper的命名服务,采用不同的目录结构存储不同模块不同服务的rmi的url,使用key来对应不同的服务.同时采用zookeeper解决了单点问题. 当有两个相同的服务注册时,因为采用的是 ...
 - MIME类型
			
多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions)是一个互联网标准,它扩展了电子邮件标准,使其能够支持非ASCII字符.二进制格式附件等多种格 ...
 - 使用supervisor的一些注意事项
			
一直都有在使用supervisor来管理linux上的服务进程.最近有同事说有某服务貌似有问题,让上去检查一下.上去以后发现某服务反应的确很慢,所以就用supervisor重启一下.但是重启的时候就发 ...
 - Power of Four
			
Given an integer (signed 32 bits), write a function to check whether it is a power of 4. Example:Giv ...
 - Java入门到精通——基础篇之static关键字
			
一.概述 static 关键字是声明静态变量,静态方法用的.static的含义是属于类且不属于类对象的变量和函数. 二.static的产生. 在创建对象的时候除非用new ...
 - EMVTag系列7《静态签名数据》
			
Ø 5F24 应用有效期 L: 3 -M(必备) 1) 芯片中的应用失效日期5F24,服务码5F30,必须与芯片中的二磁道等效数据(Tag57)中的失效日期和服务码一致. 2) qPBOC ...
 - hdu 5427 A problem of sorting
			
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5427 A problem of sorting Description There are many ...
 - Oracle ODP.NET连接池
			
数据库连接池 连接池是数据库连接的缓存,每当应用程序需要连接数据库时向连接池申请数据库连接,连接池负责具体数据库连接的创建和销毁.连接池中的数据库连接会缓存一段时间,后续的连接请求首先使用缓存中的数据 ...
 - Go循环引用问题
			
在Go中,不支持循环引用,即package a引用了packageb以后,package b就不能引用package a了. 最简单的场景: package a中定义context.go用来保存上下文 ...