bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
一直以为这题要martix-tree,实际上因为有相同权值的边不大于10条于是dfs就好了...
先用kruskal求出每种权值的边要选的次数num,然后对于每种权值的边2^num暴搜一下选择的情况算出多少种情况合法,对于每种权值的边的方案用乘法原理乘起来就是答案了
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=,mod=;
struct poi{int x,y,z,pos;}a[maxn];
int n,m,cntt,sum,cnt,ans;
int num[maxn],fa[maxn],l[maxn],r[maxn];
inline void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
bool cmp(poi a,poi b){return a.z<b.z;}
int gf(int x){return fa[x]==x?x:gf(fa[x]);}
void dfs(int w,int x,int dep)
{
if(dep>num[w])return;
if(x>r[w]){if(dep==num[w])sum++;return;}
int xx=gf(a[x].x),yy=gf(a[x].y);
if(xx!=yy)fa[xx]=yy,dfs(w,x+,dep+),fa[xx]=xx;
dfs(w,x+,dep);
}
int main()
{
read(n);read(m);
for(int i=;i<=m;i++)read(a[i].x),read(a[i].y),read(a[i].z);
sort(a+,a++m,cmp);
for(int i=;i<=m;i++)
{
if(a[i].z!=a[i-].z)r[cnt++]=i-,l[cnt]=i;
a[i].pos=cnt;
}
r[cnt]=m;
for(int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=m;i++)
{
int x=gf(a[i].x),y=gf(a[i].y);
if(x!=y)fa[x]=y,num[a[i].pos]++,cntt++;
}
if(cntt!=n-)return puts(""),;
for(int i=;i<=n;i++)fa[i]=i;ans=;
for(int i=;i<=cnt;i++)
if(num[i])
{
sum=;dfs(i,l[i],);
for(int j=l[i];j<=r[i];j++)fa[gf(a[j].x)]=gf(a[j].y);
ans=1ll*ans*sum%mod;
}
printf("%d\n",ans);
}
bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)的更多相关文章
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等 就是说如果一种方案中权值为1的边有n条 ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- bzoj1016 [JSOI2008]最小生成树计数——Kruskal+矩阵树定理
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 从 Kruskal 算法的过程来考虑产生多种方案的原因,就是边权相同的边有一样的功能, ...
- 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)
1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- BZOJ1016:[JSOI2008]最小生成树计数(最小生成树,DFS)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- bzoj1016/luogu4208 最小生成树计数 (kruskal+暴搜)
由于有相同权值的边不超过10条的限制,所以可以暴搜 先做一遍kruskal,记录下来每个权值的边使用的数量(可以离散化一下) 可以证明,对于每个权值,所有的最小生成树中选择的数量是一样的.而且它们连成 ...
随机推荐
- 学习笔记之shell命令
linux shell命令学习笔记:~这里只是对自己一些常用但是不熟悉的的命令进行记录 -------------------------------------------------------- ...
- Ubuntu 16.04 主题美化及常用软件安装
一.主题美化 系统清理 系统更新: 安装完系统之后,需要更新一些补丁.Ctrl+Alt+T调出终端,执行一下代码: sudo apt-get update sudo apt-get upgrade 卸 ...
- Tomcat源码学习(2)——启动过程分析
Tomcat启动过程分析 启动 tomcat 时,Windows下执行 startup.bat :Linux下执行 startup.sh 文件,实际上最后都是调用 org.apache.catalin ...
- k8s zookeeper、kafka部署
安装zookeeper apiVersion: v1 kind: ConfigMap metadata: name: zookeeper-config namespace: kube-system a ...
- 从零开始的Python学习Episode 13——常用模块
模块 一.time模块 时间戳(timestamp) :时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量. 元组(struct_time) :struct_time元组共有9 ...
- VisualSVN Server的迁移
VisualSVN Server迁移涉及到两种情况: 第一种情况:VisualSVN Server没有更换电脑或者服务器,只是修改Server name. 第二种情况:当VisualSVN Serve ...
- Java微笔记(9)
使用 Date 和 SimpleDateFormat 类表示时间 处理日期和时间的相关数据,可以使用 java.util 包中的 Date 类 使用 Date 类的默认无参构造方法创建出的对象就代表当 ...
- SVN版本合并技巧
公司使用了bug管理系统,项目添加新功能时,建一个主工单,再分成多个子工单,将子工单分给多个程序员来开发. 开发人员完成一部分就提交一部分,多个小功能模块就分多次提交到测试主干,然后用测试主干项目发布 ...
- Eclipse添加Jquery和javascript的智能提示
使用Eclipse写Jquery和Javascript代码的时候,是没有智能提示的.我们可以使用一个插件来解决这个问题. 安装完成后,Eclipse会自动重启.重启之后,我们在项目上右键, 根据自 ...
- lintcode-421-简化路径
421-简化路径 给定一个文档(Unix-style)的完全路径,请进行路径简化. 样例 "/home/", => "/home" "/a/./ ...