1016: [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 6200 Solved: 2518
[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
- /*
- * @Author: LyuC
- * @Date: 2017-09-07 21:48:20
- * @Last Modified by: LyuC
- * @Last Modified time: 2017-09-12 17:52:51
- */
- /*
- 题意:现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道
- 这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则
- 这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方
- 案数对31011的模就可以了。
- 思路:每个最小生成树的相同权值的边数是相同的,并且连通性是相同的,只需要枚举每个
- 权值的相同连通性,并且是最小生成树中这个权值的个数的方案数,然后组合一下就行了
- */
- #include <bits/stdc++.h>
- #define MAXN 105
- #define MAXM 1005
- #define mod 31011
- using namespace std;
- struct Edge{
- int u,v,w;
- bool operator < (const Edge & other) const{
- return w<other.w;
- }
- }edge[MAXM];
- vector<Edge>v[MAXM];
- int n,m;
- int x,y,z;
- int bin[MAXN];
- int root[MAXN];
- int vis[MAXM];//每种权值用到的数量
- int sum;
- int la;
- int pos;
- int res;
- inline int findx(int x){
- int s=x;
- while(x!=bin[x])
- x=bin[x];
- bin[s]=x;
- return x;
- }
- inline int Count(int x){
- int s=;
- while(x){
- if(x%)
- s++;
- x/=;
- }
- return s;
- }
- inline void init(){
- for(int i=;i<=n;i++){
- bin[i]=i;
- root[i]=i;
- }
- memset(vis,,sizeof vis);
- for(int i=;i<MAXM;i++)
- v[i].clear();
- res=;
- pos=;
- sum=;
- }
- int main(){
- // freopen("in.txt","r",stdin);
- scanf("%d%d",&n,&m);
- init();
- for(int i=;i<m;i++){
- scanf("%d%d%d",&x,&y,&z);
- edge[i].u=x;
- edge[i].v=y;
- edge[i].w=z;
- }
- sort(edge,edge+m);
- //处理每种权值需要的边数
- la=-;
- for(int i=;i<m;i++){
- if(edge[i].w!=la){
- la=edge[i].w;
- bool flag=false;
- for(int j=i;edge[j].w==la;j++){
- int fx=findx(edge[j].u);
- int fy=findx(edge[j].v);
- if(fx!=fy){
- flag=true;
- bin[fx]=fy;
- vis[pos]++;
- sum++;
- }
- v[pos].push_back(edge[j]);
- }
- pos++;
- }
- }
- if(sum!=n-){
- puts("");
- return ;
- }
- for(int i=;i<pos;i++){//枚举每个阶段用到权值的边
- if(vis[i]==) continue;
- int tol=(<<v[i].size());
- int cur=;//可以的方案
- for(int j=;j<tol;j++){
- if(Count(j)!=vis[i]) continue;
- bool flag=true;
- memcpy(bin,root,sizeof root);
- for(int k=;k<v[i].size();k++){
- if((j&(<<k))!=){//如果这条边存在
- int fx=findx(v[i][k].u);
- int fy=findx(v[i][k].v);
- if(fx==fy){
- flag=false;
- break;
- }else{
- bin[fx]=fy;
- }
- }
- }
- if(flag==true)
- cur++;
- }
- res=res*cur%mod;
- memcpy(bin,root,sizeof root);
- for(int j=;j<v[i].size();j++){
- int fx=findx(v[i][j].u);
- int fy=findx(v[i][j].v);
- if(fx!=fy){
- bin[fx]=fy;
- }
- }
- memcpy(root,bin,sizeof bin);
- }
- printf("%d\n",res%mod);
- return ;
- }
1016: [JSOI2008]最小生成树计数的更多相关文章
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)
1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...
- [BZOJ]1016 JSOI2008 最小生成树计数
最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数(kruskal+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1016 想也想不到QAQ 首先想不到的是:题目有说,具有相同权值的边不会超过10条. 其次:老是去想组 ...
- [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】
题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...
- BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)
题目链接 最小生成树有两个性质: 1.在不同的MST中某种权值的边出现的次数是一定的. 2.在不同的MST中,连接完某种权值的边后,形成的连通块的状态是一样的. \(Solution1\) 由这两个性 ...
- 大视野 1016: [JSOI2008]最小生成树计数(最小生成树)
总结:此类题需要耐心观察规律,大胆猜想,然后证明猜想,得到有用的性质,然后解答. 简单的说:找隐含性质. 传送门:http://61.187.179.132/JudgeOnline/problem.p ...
- 1016: [JSOI2008]最小生成树计数 - BZOJ
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
随机推荐
- Docker入门之三容器
上一篇博客学习了下镜像,今天来学习容器.容器类似一个手机中的沙盒环境,用来运行app实例.和镜像一样也是对容器的创建.删除.导出等. 由于我买的参考书中的例子好多都是基于linux的,所以我将dock ...
- 使用VMware Workstation Pro 12 虚拟机安装Mac OS系统教程 全程图解
导读:使用虚拟机安装Windows.Linux或者Ubuntu系统大家或许看了很多,但如何使用VMware Workstation Pro 12安装Mac OS,的确需要好好研究一番:否则无法下手,因 ...
- Java并发/多线程系列——初识篇
回到过去,电脑有一个CPU,一次只能执行一个程序.后来多任务处理意味着计算机可以同时执行多个程序(AKA任务或进程).这不是真的"同时".单个CPU在程序之间共享.操作系统将在运行 ...
- 课程作业02(关于Java的几点讨论)
---恢复内容开始--- 1.一个Java类文件中真的只能有一个公有类吗? public class Test { public static void main(String[] args) { } ...
- selenium webdriver 启动三大浏览器Firefox,Chrome,IE
selenium webdriver 启动三大浏览器Firefox,Chrome,IE 1.安装selenium 在联网的情况下,在Windows命令行(cmd)输入pip install selen ...
- Linux+Apache2.4+PHP5.6+MySQL5.6源码安装步骤
一.安装Apache 若要安装apache服务器软件,需要安装以下几个依赖软件 apr-1.4.6.tar.gz 下载地址:http://apr.apache.org/ apr-util-1.4.1. ...
- 使用svn控制系统的优缺点和注意事项
1.当无法连接到中央版本库的环境下,你无法提交代码,将代码加入版本控制.公司一般是局域网,所以使用环境问题不大. 2.svn的备份要备份所有代码数据以及所有更改的版本记录. 3.svn服务端运行方式: ...
- 基于LoadRunner11,以wifi热点方式录制APP脚本简单指导
本想详细写下操作过程,但并不觉着十分必要,通过baidu或我要自学网均能找到相关资料,所以详细操作过程不再赘述,只是把过程中遇到的问题说明下解释下,让大家“录制APP”的路更平坦! 1.如何使用Loa ...
- android中跨线程向控件传值的问题
activity.oncreate(bundle savedinstancestate)中创建一个handler类的实例, 在这个handler实例的handlemessage回调函数中调用更新界面显 ...
- 有趣的flash例子
仓鼠 <object type="application/x-shockwave-flash" data="http://cdn.abowman.com/widge ...