题目链接

题目

题目描述

Rinne 学到了一个新的奇妙的东西叫做动态图,这里的动态图的定义是边权可以随着操作而变动的图。

当我们在这个图上经过一条边的时候,这个图上所有边的边权都会发生变动。

定义变动函数 \(f(x) = \frac{1}{1-x}\) ,表示我们在图上走过一条边后,图的边权变动情况。

这里指的“图的变动”的意思是将每条边的边权代入上函数,得到的值即为该次变动后的边权。

现在 Rinne 想要知道,在这个变动的图上从 1 到 n 的最短路径。

因为 Rinne 不喜欢负数,所以她只需要你输出经过的边权权值绝对值之和最小的那个值就可以了。

输出答案保留三位小数。

输入描述

第一行两个正整数 N,M,表示这个动态图的点数和边数。

接下来 M 行,每行三个正整数 u,v,w,表示存在一条连接点 u,v 的无向边,且初始权值为 w。

输出描述

如果能到达的话,输出边权绝对值之和最小的答案,保留三位小数。

否则请输出 -1。

示例1

输入

3 3
1 2 2
2 3 2
3 1 3

输出

3.000

说明

走 \(1 \to 2 \to 3\) ,总花费 \(2 + |\frac{1}{1-2}| = 3\)

备注

\(n \leq 100000,m \leq 300000,2 \leq x \leq 1000\)

题解

知识点:最短路。

注意到,边权是一个周期变化 \(|x|,|\frac{1}{1-x}|,|1-\frac{1}{x}|,|x|,\cdots\) 。因此我们保存一个周期的边权跑最短路,再给 \(dis\) 加一个维度记录不同边权下的最短路。

时间复杂度 \(O((n+m)\log m)\)

空间复杂度 \(O(n+m)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; template<class T>
struct Graph {
struct edge {
int v, nxt;
T w;
};
int idx;
vector<int> h;
vector<edge> e; Graph(int n, int m):idx(0), h(n + 1), e(m + 1) {}
void init(int n) {
idx = 0;
h.assign(n + 1, 0);
} void add(int u, int v, const T &w) {
e[++idx] = edge{ v,h[u],w };
h[u] = idx;
}
}; const int N = 100000 + 7, M = 300000 + 7 << 1;
Graph<vector<double>> g(N, M);
int n, m; bool vis[N][3];
double dis[N][3];
struct node {
int v, cnt;
double w;
friend bool operator<(const node &a, const node &b) {
return a.w > b.w;
}
};
priority_queue<node> pq;
double dijkstra(int st) {
for (int i = 1;i <= n;i++) dis[i][0] = dis[i][1] = dis[i][2] = 0x3f3f3f3f;
dis[st][0] = 0;
pq.push({ st,0,0 });
while (!pq.empty()) {
int u = pq.top().v, cnt = pq.top().cnt;
pq.pop();
if (u == n) return dis[u][cnt];
if (vis[u][cnt]) continue;
vis[u][cnt] = 1;
for (int i = g.h[u];i;i = g.e[i].nxt) {
int v = g.e[i].v;
double w = g.e[i].w[cnt];
if (dis[v][(cnt + 1) % 3] > dis[u][cnt] + w) {
dis[v][(cnt + 1) % 3] = dis[u][cnt] + w;
pq.push(node{ v,(cnt + 1) % 3,dis[v][(cnt + 1) % 3] });
}
}
}
return -1;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1;i <= m;i++) {
int u, v;
double w;
cin >> u >> v >> w;
g.add(u, v, { w,abs(1 / (1 - w)),abs(1 - 1 / w) });
g.add(v, u, { w,abs(1 / (1 - w)),abs(1 - 1 / w) });
}
double ans = dijkstra(1);
if (ans < 0) cout << -1 << '\n';
else cout << fixed << setprecision(3) << ans << '\n';
return 0;
}

NC22600 Rinne Loves Dynamic Graph的更多相关文章

  1. Nowcoder contest 370H Rinne Loves Dynamic Graph【分层图最短路】

    <题目链接> 题目大意:Rinne 学到了一个新的奇妙的东西叫做动态图,这里的动态图的定义是边权可以随着操作而变动的图.当我们在这个图上经过一条边的时候,这个图上所有边的边权都会发生变动. ...

  2. HDU 6321 Dynamic Graph Matching

    HDU 6321 Dynamic Graph Matching (状压DP) Problem C. Dynamic Graph Matching Time Limit: 8000/4000 MS (J ...

  3. hdu多校第3场C. Dynamic Graph Matching

    Problem C. Dynamic Graph Matching Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Tot ...

  4. HDU6321 Dynamic Graph Matching【状压DP 子集枚举】

    HDU6321 Dynamic Graph Matching 题意: 给出\(N\)个点,一开始没有边,然后有\(M\)次操作,每次操作加一条无向边或者删一条已经存在的边,问每次操作后图中恰好匹配\( ...

  5. 论文笔记:(2019)LDGCNN : Linked Dynamic Graph CNN-Learning on PointCloud via Linking Hierarchical Features

    目录 摘要 一.引言 A.基于视图的方法 B.基于体素的方法 C.基于几何的方法 二.材料 三.方法 A.问题陈述 B.图生成 C.图特征提取 D.变换不变函数 E.LDGCNN架构 F.冻结特征提取 ...

  6. 论文笔记:(TOG2019)DGCNN : Dynamic Graph CNN for Learning on Point Clouds

    目录 摘要 一.引言 二.相关工作 三.我们的方法 3.1 边缘卷积Edge Convolution 3.2动态图更新 3.3 性质 3.4 与现有方法比较 四.评估 4.1 分类 4.2 模型复杂度 ...

  7. 论文阅读 Dynamic Graph Representation Learning Via Self-Attention Networks

    4 Dynamic Graph Representation Learning Via Self-Attention Networks link:https://arxiv.org/abs/1812. ...

  8. 论文阅读 dyngraph2vec: Capturing Network Dynamics using Dynamic Graph Representation Learning

    6 dyngraph2vec: Capturing Network Dynamics using Dynamic Graph Representation Learning207 link:https ...

  9. Nowcoder contest 370B Rinne Loves Graph 【分层图最短路】

    <题目链接> 题目大意: Island 是有一些奇怪的城镇和道路构成的(题目需要,游戏党勿喷),有些城镇之间用双向道路连接起来了,且每条道路有它自己的距离.但是有一些城镇已经被派兵戒严,虽 ...

  10. Nowcoder contest 370F Rinne Loves Edges (简单树形DP) || 【最大流】(模板)

    <题目链接> 题目大意: 一个 $n$ 个节点 $m$ 条边的无向连通图,每条边有一个边权 $w_i$.现在她想玩一个游戏:选取一个 “重要点” S,然后选择性删除一些边,使得原图中所有除 ...

随机推荐

  1. AI毕业设计生成器(基于AI大模型技术开发)

    这是一个辅助生成计算机毕业设计的工具,可以自动完成毕业设计的源码.它基于几百个github上面开源的java和python项目,运用tengsorflow技术,训练出了AI大模型.基本实现了计算机毕业 ...

  2. Prime Time - 介绍

    Prime Time是对timing进行分析 Prime Time使用的是STA方法进行分析 工具会有更新,但是核心内容是不变的 Prime Time(intro to STA) 没有PT工具的时候, ...

  3. 01-Linux命令和C语言基础

    1 Linux开发环境搭建 1.1 虚拟机安装 1.安装VM Ware 2.安装ubuntu 分区 -- Linux没有盘符的概念 / -- 5000M /boot -- 系统启动过程中读取的重要文件 ...

  4. win11不改时区,安装 android 子系统,运行android app

    win11开启虚拟机平台 下载安卓子系统 打开https://store.rg-adguard.net , 在URL中输入:https://www.microsoft.com/store/produc ...

  5. [转帖]SCSI、ISCSI、iSER、NVMe、NVMe-oF、NVMe-oF over RDMA

    在存储系统中,上层协议可以泛指"指令",也就是比如"读出从某某开始的多少长度的扇区",指令包含三大关键信息: (1)操作码:Opreation Code,或称为 ...

  6. lightning 导入数据库表的操作步骤

    lightning 导入数据库表的操作步骤 TiDB数据库备份恢复的方式与方法 1. mysqldumper 以及 mysql 导入 2. select into outfile 以及 load da ...

  7. 查看java所有的线程信息

    最近一直有一个困惑, 不知道如何查看所有的java的线程信息. 今天看blog时发现了一个简单方法 ps -Tp $pid 就可以了 也可以使用 ps- Lfp $pid的方式 这里简单写一下统计方法 ...

  8. RabbitMQ原理详解

    RabbitMQ:我们通常谈到消息队列,就会联想到这其中的三者:生产者.消费者和消息队列,生产者将消息发送到消息队列,消费者从消息队列中获取消息进行处理.对于RabbitMQ,它在此基础上做了一层抽象 ...

  9. 每日一库:使用Viper处理Go应用程序的配置

    在开发Go应用程序时,处理配置是一个常见的需求.配置可能来自于配置文件.环境变量.命令行参数等等.Viper是一个强大的库,可以帮助我们处理这些配置. 什么是Viper? Viper是一个应用程序配置 ...

  10. [3] 以逆向的角度来看循环语句——do、while、for的比较

    [3] 以逆向的角度来看循环语句--do.while.for的比较 1. do循环 ​ 先执行循环体,后比较判断 #include <stdio.h> int main(int argc, ...