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 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
随机推荐
- Java http请求和调用
关于http get和post请求调用代码以及示例. 参考:http://www.cnblogs.com/zhuawang/archive/2012/12/08/2809380.html http请求 ...
- BZOJ1059_矩阵游戏_KEY
1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec Memory Limit: 162 MB Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一 ...
- 18.Llinux-触摸屏驱动(详解)
本节的触摸屏驱动也是使用之前的输入子系统 1.先来回忆之前第12节分析的输入子系统 其中输入子系统层次如下图所示, 其中事件处理层的函数都是通过input_register_handler()函数注册 ...
- Huge Mission
Huge Mission Problem Description Oaiei is busy working with his graduation design recently. If he ca ...
- servlet自动获取前端页面提交数据
servlet自动获取前端页面jsp提交数据 以下是本人在学习过程中,因前端页面提交参数过多,后台servlet封装实体类过于麻烦而写的一个工具类,应用于jsp/servlet数据提交后,基于MVC+ ...
- Java总结篇:Java多线程
Java总结篇系列:Java多线程 多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: ...
- 应试记录2(没有转载标注,NOIP2016复赛过后自动删除)
#include<stdio.h> #include<string.h> int main() { ]; memset(a, , sizeof(a)); ;i<=;i++ ...
- 开源纯C#工控网关+组态软件(三)加入一个新驱动:西门子S7
一. 引子 首先感谢博客园:第一篇文章.第一个开源项目,算是旗开得胜.可以看到,项目大部分流量来自于博客园,码农乐园,名不虚传^^. 园友给了我很多支持,并提出了很好的改进意见.现加入屏幕分辨率自 ...
- 简单Elixir游戏服设计- 创建项目
反正是写到哪算哪. 创建umbrella项目 mix new simple_game --umbrella 创建model项目 cd simple_game\apps mix new model 创建 ...
- Python使用Scrapy爬虫框架全站爬取图片并保存本地(妹子图)
大家可以在Github上clone全部源码. Github:https://github.com/williamzxl/Scrapy_CrawlMeiziTu Scrapy官方文档:http://sc ...