牛客 Rinne Loves Dynamic Graph (最短路dp与分层最短路)

本文通过一道题目介绍了动态图的概念,其中边权会随着操作变化。问题要求找到从节点1到节点n的最短路径,使得经过的边权绝对值之和最小。文章提到了两种解决方案:最短路dp代码和分层最短路。作者通过分析题目,发现函数具有周期性,并利用Dijkstra算法解决。虽然理解还不够深入,但作者计划继续研究并分享心得。
摘要由CSDN通过智能技术生成

题目描述
Rinne 学到了一个新的奇妙的东西叫做动态图,这里的动态图的定义是边权可以随着操作而变动的图。
当我们在这个图上经过一条边的时候,这个图上所有边的边权都会发生变动。
定义变动函数 在这里插入图片描述
,表示我们在图上走过一条边后,图的边权变动情况。
这里指的“图的变动”的意思是将每条边的边权代入上函数,得到的值即为该次变动后的边权。
现在 Rinne 想要知道,在这个变动的图上从 1 到 n 的最短路径。
因为 Rinne 不喜欢负数,所以她只需要你输出经过的边权权值绝对值之和最小的那个值就可以了。
输出答案保留三位小数。
输入描述:
第一行两个正整数 N,M,表示这个动态图的点数和边数。
接下来 M 行,每行三个正整数 u,v,w,表示存在一条连接点 u,v 的无向边,且初始权值为 w。
输出描述:
如果能到达的话,输出边权绝对值之和最小的答案,保留三位小数。
否则请输出 -1。

输入
3 3
1 2 2
2 3 2
3 1 3

输出
3.000
说明
在这里插入图片描述
题目分析
刚开始见这个题目的时候我是很懵逼的,完全不知道如何下手,想了很久很久,逐渐的有点思路了…

首先我们应该对这个函数十分的敏感,因为这就是高中数学经典的一个周期函数,经过迭代我们发现他是一个以周期为3的周期函数,经过三次之后又回到了之前的值
在这里插入图片描述
其次,dp指的是一种思想,在选与不选之间,取一个最优值,我们在遍历最短路的时候,只要走过一条边那么其余所有的边都会发生改变,那么我们就用dijkstra跑出所有的情况,因为最后那个点只有三种情况,我们只需要最后在三种情况中选出最小的那个,如果最小的那个存在路径那么就是我们所需要的答案

最短路dp代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
const int inf = 0x3f3f3f3f;
double getdis(int x, int t) //分三种情况取值
{
   
   if (t == 0)
      return abs(1.0 * x);
   else if (t == 1)
      return abs(1.0 / (1.0 - x));
   else
      return abs(1.0 - 1.0 / x);
}

struct node1
{
   
   int to, w, next;
} e[maxn];

int n, m, tot;
int head[maxn];
void add(int u, int v, int w) //链式前向星加班
{
   
   e[++tot].to = v;
   e[tot].w = w;
   e[tot].next = head[u];
   head[u] = tot;
}
double dis[maxn][5];
struct node
{
   
   int id, t;
   double dis;
   bool operator<(const node x) const
   {
   
      return dis > x.dis;
   }
};
priority_queue<node> q;
bool vis[maxn]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值