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

4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1

Sample Output

8
/*
* @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]最小生成树计数的更多相关文章

  1. BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )

    不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...

  2. 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)

    1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...

  3. [BZOJ]1016 JSOI2008 最小生成树计数

    最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...

  4. 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集

    最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...

  5. 【BZOJ】1016: [JSOI2008]最小生成树计数(kruskal+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1016 想也想不到QAQ 首先想不到的是:题目有说,具有相同权值的边不会超过10条. 其次:老是去想组 ...

  6. [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】

    题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...

  7. BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)

    题目链接 最小生成树有两个性质: 1.在不同的MST中某种权值的边出现的次数是一定的. 2.在不同的MST中,连接完某种权值的边后,形成的连通块的状态是一样的. \(Solution1\) 由这两个性 ...

  8. 大视野 1016: [JSOI2008]最小生成树计数(最小生成树)

    总结:此类题需要耐心观察规律,大胆猜想,然后证明猜想,得到有用的性质,然后解答. 简单的说:找隐含性质. 传送门:http://61.187.179.132/JudgeOnline/problem.p ...

  9. 1016: [JSOI2008]最小生成树计数 - BZOJ

    Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...

随机推荐

  1. IBAction&IBOutlet

    IB:Interface Builder 1>IBAction 需要操作,例如按钮的点击 2> IBOutlet 需要获得.修改该属性 然后就可以与Storyboard建立起联系

  2. Spring+SpringMVC+MyBatis整合进阶篇(四)RESTful实战(前端代码修改)

    前言 前文<RESTful API实战笔记(接口设计及Java后端实现)>中介绍了RESTful中后端开发的实现,主要是接口地址修改和返回数据的格式及规范的修改,本文则简单介绍一下,RES ...

  3. window、linux系统与linux服务器之间使用svn同步及自动部署代码的方法

    摘要: 在家用PC,在公司用办公电脑对一个项目的代码进行修改时,会遇到代码同步的问题.本文讲解了代码同步及自动部署的解决办法. 实现方法: 1.首先在linux服务器上和linux上安装svn(sud ...

  4. win32多线程编程

    关于多线程多进程的学习,有没有好的书籍我接触的书里头关于多线程多进程部分,一是<操作系统原理>里面讲的相关概念   一个是<linux基础教程>里面讲的很简单的多线程多进程编程 ...

  5. 使用LayUI展示数据

    LayUI是一款免费,开源,轻量级的前端cms框架,适用于企业后端,能快速上手开发,集成了常用的组件,还有完善的文档和社区. 点击查看 文档地址 下载框架 使用: 1.把这个5个文件项都拷贝到项目中 ...

  6. 再起航,我的学习笔记之JavaScript设计模式28(委托模式)

    ## 委托模式 ### 概念介绍 **委托模式(Entrust): **多个对象接收并处理同一请求,他们将请求委托给另一个对象统一处理请求. ### 利用委托优化循环 如果我们有一个需求需要让用户点击 ...

  7. Zabbix(一) : 简介以及Server端安装

    一.什么是Zabbix? zabbix由AlexeiVladishev首先开发,目前在维护的是Zabbix SIA.ZABBIX是一个企业级的开源分布式监控解决方案. zabbix为监控网络和服务器的 ...

  8. Linux安装mysql-5.7.17

    一.检查系统是否有自带安装MySQL 1.检查 [root@centos ~]# rpm -qa | grep -i mysql mysql-libs-5.1.71-1.el6.x86_64 2.卸载 ...

  9. Telerik 控件 RadGridview实现绑定

    0.使用MiroModes框架请先阅读http://blogs.telerik.com/blogs/posts/10-01-20/micromodels_for_silverlight.aspx 1. ...

  10. 当谈到 GitLab CI 的时候,我们都该聊些什么(下篇)

    上篇主要介绍了 GitLab WorkFlow 以及 CI/CD 做的事情,并且详细分析 GitLab CI 跟 Runner 信息交互是如何进行的.接下来将为大家讲解 Executor 的实现,再通 ...