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. 使用ServiceDesk Plus保证及时解决问题,防止违反SLA

  2. windows下tomcat+nginx+openssl配置双向认证

    1. 基础知识 CA证书:https://blog.csdn.net/yangyuge1987/article/details/79209473 SSL双向认证原理:https://blog.csdn ...

  3. word中括号中公式对齐

    在写论文中使用到括号,但没有对齐,如: 但是我需要对齐,如: 此时只需要在每行需要对齐的地方输入‘&’即可(此符号在专业型括号是不可见的,在线性中可见,上图为专业型),同样也可以有多个对齐点, ...

  4. java 模拟登录新浪微博(通过cookie)

    这几天一直在研究新浪微博的爬虫,发现爬取微博的数据首先要登录.本来打算是通过账号和密码模拟浏览器登录.但是现在微博的登录机制比较复杂.通过账号密码还没有登录成功QAQ.所以就先记录下,通过cookie ...

  5. Codeforces Round #524 (Div. 2) E. Sonya and Matrix Beauty(字符串哈希,马拉车)

    https://codeforces.com/contest/1080/problem/E 题意 有一个n*m(<=250)的字符矩阵,对于每个子矩阵的每一行可以任意交换字符的顺序,使得每一行每 ...

  6. 剑指offer42:不用加减乘除做加法

    分析: (1)十进制加法分三步:(以5+17=22为例) 1. 只做各位相加不进位,此时相加结果为12(个位数5和7相加不进位是2,十位数0和1相加结果是1): 2. 做进位,5+7中有进位,进位的值 ...

  7. 20155205 2016-2017-2 《Java程序设计》第6周学习总结

    20155205 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 在Java中,输入串流代表对象为Java.io.InputStream实例,输出串流 ...

  8. Spring的下载与安装

    Spring是一个独立的框架,不依赖于任何Web服务器或容器.它既可在独立的JavaSE项目中使用,也可以在Java Web项目中使用. 下载和安装Spring框架可按如下步骤进行: 1.登录http ...

  9. C(m,n)算法

    排列组合:C(m,n),m为给定数列,n为要从数列m中取元素的数量,GetResult()获取所有不重复的组合. public class MathCombination<T> { Lis ...

  10. webService之helloword(java)

    webservice 远程数据交互技术 1.导入jar包(如果是 maven项目导入项目坐标) 2.创建服务 3.测试服务 我们使用maven来做测试服务 pom.xml文件 <project ...