思路 :这道题既然要求使加入生成树中的点到1号节点的距离最小,那么我们可以理解为题目要求一个最短路径生成树,那么我们可以从1号节点向每个节点跑一遍SPFA最短路,并记录下来。这道题中如果满足两个点i,j && dis[i] = dis[j] + f[i][j](dis[i]表示第i个点到1号节点的最短距离,f[i][j]表示i向j连的直接路径的长度)那么就满足题目中的条件(生成树中的某个点到1号节点的路径等于从当前点到1号节点的最短路径),所以当前点的答案数++,最后再用乘法原理把他们的方案数乘起来。

证明一下为什么 dis[i] = dis[j] + f[i][j] 答案数就++ :

如样例图所示:

我们手动模拟求得dis[1] = 0, dis[2] = 1, dis[3] = 2,  dis[4] = 3(f的就不求了)

开始模拟:

  • 第2号节点 :枚举所有点,显而易见只有dis[2] = dis[1] + f[2][1]的这种情况(每个节点都会有这种情况的,即直接走最短路)
  • 第3号节点 :枚举所有点,显而易见有两种情况,一是直接走最短路(这里就不写了),二是经过2号节点,再到达1号节点dis[3] = dis[2] + f[3][2]
  • 第4号节点 :枚举所有点,显而易见有三种情况,一是直接走最短路(这里就不写了),二是经过2号节点,再到达1号节点dis[4] = dis[2] + f[4][2],三是经过3号节点,再到达1号节点dis[4] = dis[3] + f[4][3]

综上所述,如果一个节点可以经过另一个节点到达1号节点,而且距离还是相同的,那么答案数就可以++了。这里采用了Floyed的思想

那个式子翻译成中文就是如果一个节点到1号节点的最短路 = 另一个和它有连边的节点到根节点的最短路 + 它们两个节点之间的直接距离,那么答案数++,而那条边要不然就是在最短路里,要不然就是另一种方案

code :

 #include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const long long MOD = pow(, ) - ;//别忘了取膜
int n, m, x, y, num, head[], vis[];
long long ans, z, dis[], f[][];//这些变量最好开long long
struct node
{
int next, to;
long long val;
}stu[];
inline void add(int x, int y, int z)//标准链式向前星
{
stu[++num].next = head[x];
stu[num].to = y;
stu[num].val = z;
head[x] = num;
return;
}
inline void spfa(int s)//SPFA最短路
{
memset(vis, , sizeof(vis));
memset(dis, INF, sizeof(dis));
queue < int > pru;
pru.push(s);
dis[s] = ;
vis[s] = ;
while(!pru.empty())
{
int u = pru.front();
pru.pop();
vis[u] = ;
for(register int i = head[u]; i; i = stu[i].next)
{
int k = stu[i].to;
if(dis[k] > dis[u] + stu[i].val)
{
dis[k] = dis[u] + stu[i].val;
if(!vis[k])
{
vis[k] = ;
pru.push(k);
}
}
}
}
return;
}
int main()
{
memset(f, INF, sizeof(f));//初始化
scanf("%d %d", &n, &m);
for(register int i = ; i <= m; ++i)
{
scanf("%d %d %lld", &x, &y, &z);
add(x, y, z);//无向图
add(y, x, z);
f[x][y] = f[y][x] = min(f[x][y], z);//取最小(不知道有没有毒瘤数据)
}
spfa();//从1号节点出发
ans = ;//初始化为1
for(register int i = ; i <= n; ++i)//1号节点不算
{
int sum = ;//当前节点的方案数
for(register int j = ; j <= n; ++j)//枚举
{
if(dis[i] == dis[j] + f[i][j])//不解释
{
++sum;
}
}
if(sum)//这里其实不需要特判,因为每个点都一定会有走最短路这种情况
{
ans = ans * sum % MOD;//乘法原理 + 边乘边膜
}
}
printf("%lld", ans);
return ;
}

一本通 P1486 【黑暗城堡】的更多相关文章

  1. LOJ#10064. 「一本通 3.1 例 1」黑暗城堡

    LOJ#10064. 「一本通 3.1 例 1」黑暗城堡 题目描述 你知道黑暗城堡有$N$个房间,$M$条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设$D_i$为如果 ...

  2. 信息奥赛一本通1486: CH 6202 黑暗城堡 最短路径生成树计数

    1486:黑暗城堡 [题目描述] 知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设 Di为如果所有的通道都被修建,第 i 号房间与第 1 ...

  3. 【loj10064】黑暗城堡

    #10064. 「一本通 3.1 例 1」黑暗城堡 内存限制:512 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统    评测方式:文本比较 上传者: 1bentong 提交     ...

  4. [LOJ#10064]黑暗城堡

    Description 在顺利攻破 Lord lsp 的防线之后,lqr 一行人来到了 Lord lsp 的城堡下方.Lord lsp 黑化之后虽然拥有了强大的超能力,能够用意念力制造建筑物,但是智商 ...

  5. 「CH6202」黑暗城堡

    「CH6202」黑暗城堡 传送门 这道题是要让我们求以点 \(1\) 为源点的最短路树的方案数. 我们先跑一遍最短路,然后考虑类似 \(\text{Prim}\) 的过程. 当我们把点 \(x\) 加 ...

  6. loj黑暗城堡

    黑暗城堡 题目描述 你知道黑暗城堡有\(N\)个房间,M 条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设\(D_i\)为如果所有的通道都被修建,第i号房间与第1号房间 ...

  7. LOJ10064黑暗城堡

    题目描述你知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设 Di​ 为如果所有的通道都被修建,第 i 号房间与第 1 号房间的最短路径长 ...

  8. T57274 黑暗城堡

    传送门 思路: 先求出各个点到 1 的最短路径.分别用两个数组将最短路径记录下来(一个要用来排序).按排序后的 dis 值从小到大枚举各点加入树有多少种方案,最后根据乘法原理把各个点的方案数乘起来就是 ...

  9. CH6202 黑暗城堡

    一道最短路+生成树 原题链接 实际上就是生成树的中每个点到节点\(1\)的距离等于原图中这个点到节点\(1\)的最短距离,求这样的生成树的棵数. 先用\(SPFA\)或\(Dijkstra\)求出所有 ...

随机推荐

  1. JSP一二章笔试题

    一. 什么是B/S架构,什么是C/S架构B/S(Browser/Server) 浏览器/服务器 C/S(Client/Server) 客户端/服务器 二. B/S架构的工作原理 浏览器请求服务器 通过 ...

  2. 使用ASM实现动态代理

    如果对我这段代码感兴趣,直接拷贝测试debug,要不然你不知道我写的是什么鬼,如果有什么问题,可以告诉我. 一.实现动态代理,首先得考虑有应该定义哪些类,根据JDK的动态代理思想,那么它就应该有一个生 ...

  3. SPFA队列优化

    spfa队列优化(用来求最短路) 实现方法: 1.存入图.可以使用链式前向星或者vocter. 2.开一个队列,先将开始的节点放入. 3.每次从队列中取出一个节点X,遍历与X相通的Y节点,查询比对   ...

  4. 【JDK】JDK源码分析-Vector

    概述 上文「JDK源码分析-ArrayList」主要分析了 ArrayList 的实现原理.本文分析 List 接口的另一个实现类:Vector. Vector 的内部实现与 ArrayList 类似 ...

  5. 基于JaCoCo的Android测试覆盖率统计(二)

    > 本文章是我上一篇文章的升级版本,详见地址:https://www.cnblogs.com/xiaoluosun/p/7234606.html ## 为什么要做这个?1. 辛辛苦苦写了几百条测 ...

  6. UR机器人通信--上位机通信(python)

    一.通信socket socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: socket.socket([family[, type[, proto]]]) ...

  7. 直方图均衡基本原理及Python实现

    1. 基本原理 通过一个变换,将输入图像的灰度级转换为`均匀分布`,变换后的灰度级的概率密度函数为 $$P_s(s) = \frac{1}{L-1}$$ 直方图均衡的变换为 $$s = T(r) = ...

  8. UVA11388 GCD LCM

    (链接点这儿) 题目: The GCD of two positive integers is the largest integer that divides both the integers w ...

  9. dubbokeeper-moniter部署指南

    moniter在整个dubbo架构中的角色: 使用的1.0.1版本: ## 1.0.1版本变动内容 dubbokeeper在1.0.1版本对监控数据存储模块抽离出来,做为单独的应用部署,而不是和1.0 ...

  10. Docker 核心技术

    docker是什么?为什么会出现? 容器虚拟化技术:轻量级的虚拟机(但不是虚拟机) 开发:提交代码 ——> 运维:部署 在这中间,因为环境和配置,出现问题 ——> 把代码/配置/系统/数据 ...