码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5361(2015多校6)--In Touch(变形的dijkstra)

时间:2015-08-12 11:39:31      阅读:107      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:点击打开链接

题目大意:给出一个n个数的序列,标号为1到n,对于第i个数,它可以移动到距离i为[ li,ri ]的位置,花费为c[i],输入三行,第一行l[i],第二行r[i],第三行c[i],现在问对于第一个数来说,它移动到第i个位置的最小花费。(1<=i<=n)

这是一个每个点可以移动到一段中任意一个点,并且花费一样,这样就不适用与已有的四种最短路,但是可以对dijkstra进行变形,dij是每次找到一个距离最小的节点,用这个节点去更新其它节点,我们可以用一个优先队列,每次找到一个点,用这个点去更新其他的点,这个点要满足 dis[i]+c[i]是最小的,那么这个点更新出来的点也就是最小的。

有优先队列维护dis+c的值,用set来找到一段中还没有更新的点,这样就可以防止会遍历到已经更新好的点,造成超时。

#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <algorithm>
using namespace std ;
#define LL __int64
#pragma comment(linker, "/STACK:102400000,102400000")
struct node{
    int id ;
    LL c ;
    bool operator < (node a) const {
        return c > a.c ;
    }
} p , q ;
priority_queue<node> que ;
set<int> s ;
set<int> ::iterator iter ;
LL dis[200010] , c[200010] ;
int l[200010] , r[200010] ;
void f(int l,int r) {
    iter = s.lower_bound(l) ;
    while( iter != s.end() ) {
        if( *iter > r ) break ;
        dis[ *iter ] = p.c ;
        q.id = *iter ;
        q.c = p.c + c[ q.id ] ;
        que.push( q ) ;
        iter++ ;
        s.erase(q.id) ;
    }
    return ;
}
int main() {
    int t , n , i , x , y ;
    //freopen("1009.in","r",stdin) ;
    //freopen("111.out","w",stdout) ;
    scanf("%d", &t) ;
    while( t-- ) {

        while( !que.empty() ) que.pop() ;
        memset(dis,-1,sizeof(dis)) ;
        s.clear() ;
        scanf("%d", &n) ;

        for(i = 2 ; i <= n ; i++) s.insert(i) ;
        for(i = 1 ; i <= n ; i++) scanf("%d", &l[i]) ;
        for(i = 1 ; i <= n ; i++) scanf("%d", &r[i]) ;
        for(i = 1 ; i <= n ; i++) scanf("%I64d", &c[i]) ;
        dis[1] = 0 ;
        p.id = 1 ;
        p.c = c[1] ;
        que.push(p) ;
        while( !que.empty() && !s.empty() ) {
            p = que.top() ;
            que.pop() ;
            x = max(p.id - r[ p.id ],1) ;
            y = p.id - l[ p.id ] ;
            if( y >= 1 ) f(x,y) ;
            x = p.id + l[ p.id ] ;
            y = min(p.id + r[ p.id ],n) ;
            if( x <= n ) f(x,y) ;

        }
        for(i = 1 ; i < n ; i++)
            printf("%I64d ", dis[i]) ;
        printf("%I64d\n", dis[i]) ;
    }
    return 0 ;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu5361(2015多校6)--In Touch(变形的dijkstra)

标签:

原文地址:http://blog.csdn.net/winddreams/article/details/47440423

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!