[BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】
题目链接:BZOJ - 1016
题目分析
最小生成树的两个性质:
同一个图的最小生成树,满足:
1)同一种权值的边的个数相等
2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性相等
这样,先做一次Kruscal求出每种权值的边的条数,再按照权值从小到大,对每种边进行 DFS, 求出这种权值的边有几种选法。
最后根据乘法原理将各种边的选法数乘起来就可以了。
特别注意:在DFS中为了在向下DFS之后消除决策影响,恢复f[]数组之前的状态,在DFS中调用的Find()函数不能路径压缩。
代码
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm> using namespace std; const int MaxN = 100 + 5, MaxM = 1000 + 5, Mod = 31011; int n, m, Top, Sum, Cnt;
int f[MaxN], L[MaxM], R[MaxM], Num[MaxM]; typedef long long LL;
LL Ans; struct Edge
{
int u, v, w;
} E[MaxM]; inline bool Cmp(Edge e1, Edge e2)
{
return e1.w < e2.w;
} inline int Find(int x, int o)
{
int i, j, k;
j = x;
while (j != f[j]) j = f[j];
if (o == 1) return j;
i = x;
while (i != j)
{
k = i;
i = f[i];
f[k] = j;
}
return j;
} void DFS(int Type, int x, int y)
{
if (x == R[Type] + 1)
{
if (y == Num[Type]) ++Cnt;
return;
}
int fx, fy;
fx = Find(E[x].u, 1); fy = Find(E[x].v, 1);
if (fx != fy)
{
f[fx] = fy;
DFS(Type, x + 1, y + 1);
f[fx] = fx;
}
DFS(Type, x + 1, y);
} int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; ++i)
scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].w);
sort(E + 1, E + m + 1, Cmp);
Top = 0; Sum = 0;
int fx, fy;
for (int i = 1; i <= n; ++i) f[i] = i;
for (int i = 1; i <= m; ++i)
{
if (i == 1 || E[i].w != E[i - 1].w) L[++Top] = i;
R[Top] = i;
fx = Find(E[i].u, 0); fy = Find(E[i].v, 0);
if (fx != fy)
{
f[fx] = fy;
++Num[Top];
++Sum;
}
}
if (Sum != n - 1)
{
printf("0\n");
return 0;
}
for (int i = 1; i <= n; ++i) f[i] = i;
Ans = 1;
for (int i = 1; i <= Top; ++i)
{
if (Num[i] == 0) continue;
Cnt = 0;
DFS(i, L[i], 0);
Ans = Ans * (LL)Cnt % Mod;
for (int j = L[i]; j <= R[i]; ++j)
{
fx = Find(E[j].u, 0); fy = Find(E[j].v, 0);
if (fx != fy) f[fx] = fy;
}
}
printf("%d\n", (int)Ans);
return 0;
}
[BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】的更多相关文章
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- [BZOJ]1016 JSOI2008 最小生成树计数
最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...
- bzoj 1016: [JSOI2008]最小生成树计数【dfs+克鲁斯卡尔】
有一个性质就是组成最小生成树总边权值的若干边权总是相等的 这意味着按边权排序后在权值相同的一段区间内的边能被选入最小生成树的条数是固定的 所以先随便求一个最小生成树,把每段的入选边数记录下来 然后对于 ...
- BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)
题目链接 最小生成树有两个性质: 1.在不同的MST中某种权值的边出现的次数是一定的. 2.在不同的MST中,连接完某种权值的边后,形成的连通块的状态是一样的. \(Solution1\) 由这两个性 ...
- bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 就是缩点,每次相同权值的边构成的联通块求一下matrix tree.注意gauss里的 ...
- BZOJ 1016 [JSOI2008]最小生成树计数 ——Matrix-Tree定理
考虑从小往大加边,然后把所有联通块的生成树个数计算出来. 然后把他们缩成一个点,继续添加下一组. 最后乘法原理即可. 写起来很恶心 #include <queue> #include &l ...
- 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)
1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...
- 1016: [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6200 Solved: 2518[Submit][St ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...
随机推荐
- bash if 表达式
.bash把[[ $a -lt $b ]]看作一个单独的元素,并且返回一个退出码.退出码0为真,非零为假 例如: a= b=c [[ $a -lt $b ]] echo $? # a小于b为真 [[ ...
- Linux学习笔记总结--memcached配置
Memcached是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果等.简单的说就是将数据调用到 ...
- Elasticsearch .Net Client NEST使用说明 2.x
Elasticsearch .net client NEST使用说明 2.x Elasticsearch.Net与NEST是Elasticsearch为C#提供的一套客户端驱动,方便C#调用Elast ...
- javascript常用方法(慢慢整理)
获取类型:[object object],[object function],[object Undefined]等 Object.prototype.toString.apply(obj); 获取对 ...
- 浅析@Deprecated
如果有一个方法你觉得不合适,想要删除,但是别人已经引用了很多次,删除了会对他人的工作产生影响,那该怎么办? 加入@Deprecated注解即可,看代码: @Test public void test1 ...
- Android开发之Activity(活动)
在安卓中,Activity(活动)就是一个包含应用程序的用户界面的窗口.一个应用程序可以包含一个或多个Activity. 一般一个活动对应一个UI文件,即xml文件.创建活动一般是基础Activity ...
- PHP5常量
用函数 define()设置常量 define函数有3个参数 1.必选,常量的名称,标识符 2.必选,常量的值 3.可选,默认不设置,常量名称大小写敏感.如果设置true,常量名称不区分大小写! 下面 ...
- CentOS 6.7 配置nginx支持SSL/https访问
一.安装必要的包 yum install openssl openssl-devel 二.配置编译参数,增加对SSL的支持 ./configure –with-http_ssl_module 三.修改 ...
- PhotoShop常用快捷键(1)
一.工具栏工具 移动工具 [V] 矩形.椭圆选框工具 [M] 套索.多边形套索.磁性套索 [L] 快速选择.魔棒工具[W] 裁剪工具 [C] 吸管.颜色取样器 [I] 修补.污点修复[J] 画笔工具 ...
- Mysql INNER,LEFT ,RIGHT join的使用
JOIN 按照功能大致分为如下三类: INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录. LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录. RIG ...