BZOJ 1016--[JSOI2008]最小生成树计数(kruskal&搜索)
1016: [JSOI2008]最小生成树计数
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 7429 Solved: 3098
[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
题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=1016
Solution
首先可以发现在不同的最小生成树中,同权值的边的数量是一样的。。
于是可以将每种权值的边的贡献分开算,然后用乘法原理就可以了。。
对于某一种颜色,直接爆搜。。。感觉复杂度好像不太对。。。但是过了。。。
算了反正都不知道多久之前写的了。。。
代码
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #define M 1010
- #define mod 31011
- using namespace std;
- int n,m,cnt,tot;
- int f[M],w[M],sum[M];
- bool c[M];
- struct edge{
- int l,r,w;
- }e[M],a[M];
- bool cmp(edge p,edge q){return p.w<q.w;}
- int find(int x){
- if(f[x]==x) return f[x];
- return find(f[x]);
- }
- void RE(){for(int i=1;i<=n;i++) f[i]=i;}
- void dfs(int x,int now,int k){
- if(now==a[x].r+1){
- if(k==a[x].w)tot++;
- return;
- }
- int xx=find(e[now].l),yy=find(e[now].r);
- if(xx!=yy){
- f[xx]=yy;
- dfs(x,now+1,k+1);
- f[xx]=xx;f[yy]=yy;
- }
- dfs(x,now+1,k);
- }
- int main(){
- int ans=1;
- cnt=0;tot=0;
- int xx,yy;
- scanf("%d%d",&n,&m);
- for(int i=1;i<=m;i++)
- scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].w);
- sort(e+1,e+1+m,cmp);
- RE();
- for(int i=1;i<=m;i++){
- if(e[i].w!=e[i-1].w){a[cnt].r=i-1;cnt++;a[cnt].l=i;}
- xx=find(e[i].l);yy=find(e[i].r);
- if(xx!=yy){f[xx]=yy;a[cnt].w++;tot++;}
- }
- a[cnt].r=m;
- if(tot+1!=n){printf("0\n");return 0;}
- RE();
- for(int i=1;i<=cnt;i++){
- tot=0;
- dfs(i,a[i].l,0);
- ans=(ans*tot)%mod;
- for(int j=a[i].l;j<=a[i].r;j++){
- xx=find(e[j].l);yy=find(e[j].r);
- if(xx!=yy) f[xx]=yy;
- }
- }
- printf("%d\n",ans);
- return 0;
- }
This passage is made by Iscream-2001.
BZOJ 1016--[JSOI2008]最小生成树计数(kruskal&搜索)的更多相关文章
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- [BZOJ]1016 JSOI2008 最小生成树计数
最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...
- [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】
题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...
- 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 ...
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等 就是说如果一种方案中权值为1的边有n条 ...
随机推荐
- Web Api 2 认证与授权 2
HTTP Message Handler 在 Web Api 2 认证与授权 中讲解了几种实现机制,本篇就详细讲解 Message Handler 的实现方式 关于 Message Handler 在 ...
- 【C#】解析C#程序集的加载和反射
目录结构: contents structure [+] 程序集 程序集的加载 发现程序集中的类型 反射对类型成员的常规操作 发现类型的成员 创建类型的实例 绑定句柄减少进程的内存消耗 解析自定义特性 ...
- HTML and CSS学习概述-续
1, CSS是层叠样式表(Cascading Style Sheets)的缩写,它用于定义HTML元素的显示形式,是一种格式化网页内容的技术.CSS现在已经被大多数浏览器所支持,成为网页设计者必须 ...
- [RequireComponent(typeof(....))]
RequireComponent的使用: 当你添加的一个用了RequireComponent组件的脚本,需要的组件将会自动被添加到game object(游戏物体).这个可以有效的避免组装错误.举个例 ...
- *1LL在c++中的意义
LL其实代表long long,*1LL是为了在计算时,把int类型的变量转化为long long,然后再赋值给long long类型的变量 ANS=1LL*num*((1LL)*n*(n-1))/2 ...
- win/mac平台搭建ionic开发环境教程(转)
出处:http://www.ionic-china.com/doc/ionic-winmac.html#preface 前言 ionic中文网为大家准备了绿色版的nodejs和androidSDK以及 ...
- L1范式和L2范式
正则化(Regularization) 机器学习中几乎都可以看到损失函数后面会添加一个额外项,常用的额外项一般有两种,一般英文称作ℓ1ℓ1-norm和ℓ2ℓ2-norm,中文称作L1正则化和L2正则化 ...
- Ng第一课:引言(Introduction)
Machine Learning(机器学习)是研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能. 它是人工智能的核心,是使计算机具有智能的根本 ...
- bzoj2004(矩阵快速幂,状压DP)
每个长度为p的区间都必须出现k次1,数据又很小,我们使用状压. dp[i][j]->dp[i+1][j'],dp[i][j]表示当前考虑到了第i个车站,包括第i个其后的p个的状态(有车停或没车停 ...
- (最短路 弗洛伊德) Til the Cows Come Home -- POJ --2387
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> ...