思路 :这道题既然要求使加入生成树中的点到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. perspective transform透视矩阵快速求法+矩形矫正

    算了半天一直在思考如何快速把矩阵算出来,网上基本都是在说边长为1的正方形的变换方式=.=   不怎么用得上…… 公式推导推半天,计算还麻烦.... ++++++++++++++++++++++++++ ...

  2. Java核心技术(卷一)读书笔记——第二章(JAVA/JDK环境配置)

    JDK 配置:自行百度. 存在多个JDK 版本并且需要指定某版本时,注意更改注册表JavaSoft项以及相关子项,同时删除system32目录下相关的Java可执行文件xxx.exe. IDEA打开项 ...

  3. IIS网站服务器性能优化攻略

    Windows Server自带的互联网信息服务器(Internet Information Server,IIS)是架设网站服务器的常用工具,它是一个既简单而又麻烦的东西,新手都可以使用IIS架设一 ...

  4. webapck小知识点1

    全局安装webpack webpack-cli npm install webapck webpack-cli -g 卸载全局安装的webpack webpack-cli npm unistall w ...

  5. Selenium+java - 下拉框处理

    常见下拉框也分两种:一种是标准控件和非标准控件(一般为前端开发人员自己封装的下拉框),本篇文章中将重点讲解标准下拉框操作. 1.Select提供了三种选择某一项的方法 select.selectByI ...

  6. .NET Core CSharp 中级篇 2-2 List,ArrayList和Dictionary

    .NET Core CSharp 中级篇 2-2 本节内容为List,ArrayList,和Dictionary 简介 在此前的文章中我们学习了数组的使用,但是数组有一个很大的问题就是存储空间不足,我 ...

  7. ASP.NET Core MVC 之控制器(Controller)

    操作(action)和操作结果(action result)是 ASP.NET MVC 构建应用程序的一个基础部分. 在 ASP.NET MVC 中,控制器用于定义和聚合一组操作.操作是控制器中处理传 ...

  8. JavaWeb——Servlet开发2

    1.HttpServletRequest的使用 获取Request的参数的方法. 方法getParameter将返回参数的单个值 方法getParameterValues将返回参数的值的数组 方法ge ...

  9. 自己实现spring核心功能 一

    聊聊spring spring对于java开发者来说,是最熟悉不过的框架了,我们日常开发中每天都在使用它.它有着各种各样的好处,简单易用,得心应手... ... 我们一说到spring就会讲到ioc ...

  10. Java虚拟机日志与参数

    虚拟机日志 打印GC日志可以使用参数-XX:+PrintGC /** * -Xmx10m -Xms10m -XX:PretenureSizeThreshold=10485760 * -XX:+Prin ...