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

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

Sample Output

8
 

题目链接:

    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&搜索)的更多相关文章

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

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

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

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

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

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

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

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

  5. bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 就是缩点,每次相同权值的边构成的联通块求一下matrix tree.注意gauss里的 ...

  6. bzoj 1016: [JSOI2008]最小生成树计数【dfs+克鲁斯卡尔】

    有一个性质就是组成最小生成树总边权值的若干边权总是相等的 这意味着按边权排序后在权值相同的一段区间内的边能被选入最小生成树的条数是固定的 所以先随便求一个最小生成树,把每段的入选边数记录下来 然后对于 ...

  7. BZOJ 1016 [JSOI2008]最小生成树计数 ——Matrix-Tree定理

    考虑从小往大加边,然后把所有联通块的生成树个数计算出来. 然后把他们缩成一个点,继续添加下一组. 最后乘法原理即可. 写起来很恶心 #include <queue> #include &l ...

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

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

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

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 6200  Solved: 2518[Submit][St ...

  10. bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)

    1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等  就是说如果一种方案中权值为1的边有n条 ...

随机推荐

  1. Linux学习笔记:Jenkins安装

    操作系统是CentOS 7,安装Jenkins 首先安装jdk,可在Oracle jdk和Openjdk中任选其一安装Oracle jdk步骤见:   https://www.cnblogs.com/ ...

  2. SpringMVC 学习 八 SSM环境搭建(一) web.xml配置

    第一步:导入jar包 注意包的兼容性,以后采用maven会好很多 第二步:配置web.xml 在web.xml中,主要的配置内容有以下几点 (1)spring容器配置文件的位置 <!-- spr ...

  3. 过河卒(NOIP2002)

    题目链接:过河卒 直接模拟?会T掉60分. 所以我们可以采用递推,怎么想到的? 因为卒子只能向下或向右走,所以走到一个点的方法数,等于走到它上面点的方法数加上走到它左边点的方法数,这样就可以地推了. ...

  4. 9月list

    开学了,我已经是大三的老学姐了,难受! 哇,时间过得好快啊,感觉自己快毕业了,肿么办!!! 9月了,快一年了,其实很多东西都变了,比如你. 9月4日的list:

  5. python之初级篇2

    一.数字类型 1)整数 int 类型 - bit_length() # 查询以二进制表示一个数字的值所需的位数 - int.from_bytes(bytes,byteorder) # 返回给定字节数组 ...

  6. linux代码笔记

    sudo passwd root更新root密码 软件包管理及shell命令_deb软件包管理一_笔记:dpkj -i 安装dpkj -r 移除dpkj -P 全部移除dpkj -L 列出安装清单dj ...

  7. ODT(old driver tree)详解(带例题)

    文章目录 ODT简介 实现前提&&实现原理 初始化 split操作 assign操作 其它操作 区间第k小 区间加 区间所有数的k次方和 几道水题 ODT简介 ODT(old driv ...

  8. java 判断对象是否是某个类的类型两种方法

    第一种: instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 用法: resul ...

  9. SpringBoot中用Fastjson替换默认的Jackson

    一:前言 经过测试,Jackson有很多不合人意的地方,因此建议用Fastjson来替换: 二:Jackson的坑 先定义实体类: @Data @AllArgsConstructor @NoArgsC ...

  10. mysql碰到unknown variable 'xxxx' 的解决方法

    在使用mysqlbinlog查看日志的时候碰到了一个问题, 错误提示如下: /usr/local/mysql/bin/mysqlbinlog: unknown variable 'default-ch ...