首页 > 其他分享 >1032 Rinne Loves Dynamic Graph 循环分层图 最短路

1032 Rinne Loves Dynamic Graph 循环分层图 最短路

时间:2022-08-23 19:46:16浏览次数:78  
标签:pq Rinne int Graph 边权 Dynamic MAX include dis

 链接:https://ac.nowcoder.com/acm/contest/26077/1032
来源:牛客网

题目描述

Rinne 学到了一个新的奇妙的东西叫做动态图,这里的动态图的定义是边权可以随着操作而变动的图。
当我们在这个图上经过一条边的时候,这个图上所有边的边权都会发生变动。
定义变动函数 f(x)=11−xf(x) = \frac{1}{1-x}f(x)=1−x1​,表示我们在图上走过一条边后,图的边权变动情况。 这里指的“图的变动”的意思是将每条边的边权代入上函数,得到的值即为该次变动后的边权。 现在 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→2→31 \to 2 \to 31→2→3,总花费 2+∣11−2∣=32 + |\frac{1}{1-2}| = 32+∣1−21​∣=3

备注:

n≤100000,m≤300000,2≤x≤1000n \leq 100000,m \leq 300000,2 \leq x \leq 1000n≤100000,m≤300000,2≤x≤1000

分析

由于 x = 1 / 1 - x

x' = 1 / (1 - 1 / (1 - x)) 

x'' = 1 / 1 - x' = x

所以三者构成三个循环层,

将第一层指向第二层,第二层指向第三层,第三层指向第一层

再跑一边dijkstra,然后枚举最小值就可以了。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
typedef pair<int,double> PID;
typedef pair<double,int> PDI;
const double INF = 99999999999;
int n,m;
//vector<PID > vv[3*MAX];
double dis[MAX*3];
bool vis[MAX*3];
int head[MAX*3];
struct Node {
    int to,ne;
    double w;
} e[MAX*15];
int tot;
void add(int u,int v,double w) {
    e[++tot].to = v;
    e[tot].w = w;
    e[tot].ne = head[u];
    head[u] = tot;
}
void Dijkstra() {
    for(int i = 1; i<=3*n; i++) dis[i] = INF;
    dis[1] = 0;
    priority_queue<PDI> pq;
    pq.push(pm(0,1));
    while(!pq.empty()) {
        PDI cur = pq.top();pq.pop();
        if(vis[cur.se]) continue;
        vis[cur.se] = 1;
        for(int i = head[cur.se]; i!=-1; i=e[i].ne) {
            int v = e[i].to;
            if(dis[cur.se] + e[i].w < dis[v]) {
                dis[v] = dis[cur.se] + e[i].w;
                pq.push(pm(-dis[v],v));
            }
        }
    }
}
int main()
{
    memset(head,-1,sizeof head);
    cin>>n>>m;
    int u,v;
    double w;
    for(int i = 1; i<=m; i++) {
        scanf("%d%d%lf",&u,&v,&w);
        //w = fabs(w);
        add(u,v+n,fabs(w));
        add(v,u+n,fabs(w));
        w = (1.0/(1-w));
        add(u+n,v+2*n,fabs(w));
        add(v+n,u+2*n,fabs(w));
        w = (1.0/(1-w));
        add(u+2*n,v,fabs(w));
        add(v+2*n,u,fabs(w));
    }
    Dijkstra();
    double ans = INF;
    for(int i = 0; i<=2; i++) {
        ans = min(ans,dis[n+i*n]);
    }
    if(ans > 9999999999) printf("-1\n");
    else printf("%.3lf\n",ans);
 
    return 0 ;
 }

 

标签:pq,Rinne,int,Graph,边权,Dynamic,MAX,include,dis
From: https://www.cnblogs.com/er007/p/16617518.html

相关文章