HDU 5361 最短路变形

Posted Dan__ge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5361 最短路变形相关的知识,希望对你有一定的参考价值。

点击打开链接

题意:给了n个点排成一行,每两个距离为1,然后对于每个点来说它有个L和R,意思是距离在L到R中间的所有点它都能到达,费用是C,问从小出发的单源所有的点的距离

思路:看了网上神犇的题解有了点思路,因为每个点出去的费用都是相同的,而且费用的值大于0,那么1点直接到达的所有点的最短路就不需要在更新了,因为剩下的肯定是比它大的,那么对于这些个点我们压入队列,但是注意我们这里的dis设定为点的加和,然后出发的又是最短的,到达的没有访问过的点又是最小的,所以不需要最短路时的一个点可以访问多次更新最小值,然后对于访问过的点我们可以用并查集来判断,对于一个点来说,它若访问过则与右边的点合并,这样我们就可以直接访问下一个没被访问过的点,而不需要暴力寻找了,优化的就是这里

#pragma comment(linker, "/STACK:102400000,102400000")
#include <queue>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=200010;
typedef pair<ll,int> P;
int L[maxn],R[maxn],f[maxn],n;
ll dis[maxn],C[maxn];
int find1(int x)
    if(x!=f[x]) f[x]=find1(f[x]);
    return f[x];

void unite(int a,int b)
    int aa=find1(a);
    int bb=find1(b);
    if(aa==bb) return ;
    f[aa]=bb;

void dijkstra(int s)
    priority_queue<P,vector<P>,greater<P> >que;
    memset(dis,INF,sizeof(dis));
    dis[s]=C[s];
    que.push(P(0,s));
    while(!que.empty())
        P p=que.top();que.pop();
        int v=p.second;
        for(int i=-1;i<=1;i+=2)
            int le=v+i*L[v];
            int ri=v+i*R[v];
            if(le>ri) swap(le,ri);
            le=max(1,le);
            ri=min(ri,n);
            if(le>ri) continue;
            int ff=le;
            while(1)
                ff=find1(ff);
                if(ff>ri) break;
                if(dis[ff]>dis[v]+C[ff])
                    dis[ff]=dis[v]+C[ff];
                    que.push(P(dis[ff],ff));
                
                unite(ff,ff+1);
                ff++;
            
        
    

int main()
    int T;
    scanf("%d",&T);
    while(T--)
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&L[i]);
        for(int i=1;i<=n;i++) scanf("%d",&R[i]);
        for(int i=1;i<=n;i++) scanf("%I64d",&C[i]);
        for(int i=1;i<n+5;i++) f[i]=i;
        dijkstra(1);
        for(int i=1;i<=n;i++)
            if(dis[i]!=INF)
                if(i==n) printf("%I64d\\n",dis[i]-C[i]);
                else printf("%I64d ",dis[i]-C[i]);
            else
                if(i==n) printf("-1\\n");
                else printf("-1 ");
            
        
    
    return 0;

以上是关于HDU 5361 最短路变形的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4318 图论之最短路变形

Aizu 2249Road Construction 单源最短路变形《挑战程序设计竞赛》模板题

hdu 6201 transaction (最短路变形——带负权最长路)

HDU 5876 补图 单源 最短路

HDU - 3499 Flight (单源最短路+优惠问题)

hdu 2544 单源最短路问题 dijkstra+堆优化模板