bzoj1016/luogu4208 最小生成树计数 (kruskal+暴搜)
由于有相同权值的边不超过10条的限制,所以可以暴搜
先做一遍kruskal,记录下来每个权值的边使用的数量(可以离散化一下)
可以证明,对于每个权值,所有的最小生成树中选择的数量是一样的、而且它们连成的连通块也是一样的
所以我们把每个权值的边分开暴搜所有可能的情况,最后再乘到一起就是答案
#include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=,maxm=,P=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} struct Edge{
int a,b;
ll l;
}eg[maxm];
int egh[maxn],ect;
int N,M,L,cnt[maxm];
int fa[maxn],ans,sum; inline bool cmp(Edge a,Edge b){return a.l<b.l;}
inline int getf(int x){
while(x!=fa[x]) x=fa[x];return x;
} void dfs(int x,int y,int n){
if(x>M||eg[x].l!=y){
if(n==cnt[y]) sum=(sum+)%P;
return;
}
int aa=getf(eg[x].a),bb=getf(eg[x].b);
if(aa!=bb){
fa[aa]=bb;
dfs(x+,y,n+);
fa[aa]=aa;
}
dfs(x+,y,n);
} int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd(),M=rd();
for(i=;i<=M;i++){
eg[i].a=rd(),eg[i].b=rd();
eg[i].l=rd();
}sort(eg+,eg+M+,cmp);
int lst=-;
for(i=,j=;i<=M;i++){
if(eg[i].l!=lst) j++;
lst=eg[i].l,eg[i].l=j;
}
for(i=;i<=N;i++) fa[i]=i;
for(i=,j=;i<=M;i++){
int x=getf(eg[i].a),y=getf(eg[i].b);
if(x!=y){
fa[x]=y;
j++;cnt[eg[i].l]++;
}
}
if(j<N-){printf("0\n");return ;}
for(i=;i<=N;i++) fa[i]=i;
int ans=;
for(i=,j=;i<=M;i++){
if(eg[i].l!=eg[i-].l){
sum=;dfs(i,eg[i].l,);
ans=(ans*sum)%P;
}
int x=getf(eg[i].a),y=getf(eg[i].b);
if(x!=y){
fa[x]=y;j++;
}
}
printf("%d\n",ans);
return ;
}
bzoj1016/luogu4208 最小生成树计数 (kruskal+暴搜)的更多相关文章
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等 就是说如果一种方案中权值为1的边有n条 ...
- [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- bzoj1016 [JSOI2008]最小生成树计数——Kruskal+矩阵树定理
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 从 Kruskal 算法的过程来考虑产生多种方案的原因,就是边权相同的边有一样的功能, ...
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
一直以为这题要martix-tree,实际上因为有相同权值的边不大于10条于是dfs就好了... 先用kruskal求出每种权值的边要选的次数num,然后对于每种权值的边2^num暴搜一下选择的情况算 ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- 【kruscal】【最小生成树】【搜索】bzoj1016 [JSOI2008]最小生成树计数
不用Matrix-tree定理什么的,一边kruscal一边 对权值相同的边 暴搜即可.将所有方案乘起来. #include<cstdio> #include<algorithm&g ...
- [BZOJ1016][JSOI2008]最小生成树计数(结论题)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1016 分析: 首先有个性质:如果边集E.E'都可以表示一个图G的最小生成树(当然E和E ...
随机推荐
- Js读取XML文件为List结构
习惯了C#的List集合,对于Javascript没有list 极为不舒服,在一个利用Js读取XML文件的Demo中,决定自己构建List对象,将数据存入List. 第一步,Js读取XML文件知识 X ...
- Qt 的线程与事件循环
Qt 的线程与事件循环
- P3426 [POI2005]SZA-Template
P3426 [POI2005]SZA-Template 链接 分析: 首先T一定是S的一个前缀,也是一个后缀. 判断一个前缀s[1...i]是不是满足条件,那么求出s[1...i]在s中出现的所有位置 ...
- arduino驱动安装
方法一:使用官方提供的一键安装程序安装 打开Arduino在你电脑上的位置如果你的电脑是32位系统,就运行dpinst-x86.exe如果是64位系统,就运行dpinst-amd64.exe然后在弹出 ...
- webWorker
一.webWorker之初体验 在"setTimeout那些事儿"中,说到JavaScript是单线程.也就是同一时间只能做同一事情. 也好理解,作为浏览器脚本语言,如果JavaS ...
- java第二次实验报告
课程:Java实验 班级:201352 姓名:池彬宁 学号:20135212 成绩: 指导教师:娄佳鹏 实验日期:15.05.05 实验密级: ...
- 冲刺Two之站立会议3
今天继续昨天的工作,对主界面进行设计优化,并成功将各个按钮和对应的功能模块连接了起来.并对服务器部分进行了部分改进,包括登录界面的美观性和服务器数据库部分的处理.
- C#程序分析
一.程序及问题 阅读下面程序,请回答如下问题: 问题1:这个程序要找的是符合什么条件的数? 问题2:这样的数存在么?符合这一条件的最小的数是什么? 问题3:在电脑上运行这一程序,你估计多长时间才能输出 ...
- nginx转发swoole以及nginx负载
nginx作为静态服务器同时转发swoole配置: location /{root //静态文件目录;index index.html index.htm;//默认首页 if(!-e $request ...
- 从零开始学Kotlin-数据类型(2)
从零开始学Kotlin基础篇系列文章 基本数据类型 Kotlin 的基本数值类型包括 Byte.Short.Int.Long.Float.Double 等: 数据-------位宽度 Double-- ...