• hdu 4725 带层的最短路


    题意:n个点,m条边,以及相邻层之间移动的代价c,给出每个点所在的层数,以及m条边,

    每条边有u,v,c,表示从节点u到v(无向),并且移动的代价 c ,问说从 1 到 n 的代价最小是多少。

    参考 https://www.cnblogs.com/kuangbin/archive/2013/09/11/3315071.html

    思路:

    最短路。主要是建图。

    N个点,然后有N层,要增加2*N个点。总共是3*N个点。

    点1~N就是对应的实际的点1~N.  要求的就是1到N的最短路。

    然后点N+1 ~ 3*N 是N层拆出出来的点。

    第i层,入边到N+2*i-1, 出边从N+2*i 出来。(1<= i <= N)

    N + 2*i    到  N + 2*(i+1)-1 加边长度为C. 表示从第i层到第j层。

    N + 2*(i+1) 到 N + 2*i - 1 加边长度为C,表示第i+1层到第j层。

    如果点i属于第u层,那么加边 i -> N + 2*u -1         N + 2*u ->i  长度都为0

    就是说 点 x  与之对应的层点有2个, 到一个 a 入度为1,权值为0 ,一个 b 出度为1 权值为 0

    由于层之间的移动, 假设y对应层和他是相邻的, 那么c,d   需要添加 a->d  和 c->b 两个边 

    来表示于  x->a->d->y  y->c->b->a... 这样最短路也要是3*n  了

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<cmath>
    using namespace std;
    
    #define ll long long
    #define pb push_back
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    
    const int N = 3e5+4;
    const int INF = 1e9+3;
    
    
    //https://www.cnblogs.com/kuangbin/archive/2013/09/11/3315071.html
    
    struct node{
        int to,cost;
    };
    vector<node>V[N];
    int d[N];
    int n,m,c;
    void add(int u,int v,int c){
        V[u].pb( node{v,c});
    }
    void dij(){
    
        for(int i=1;i<=n;++i)d[i]=INF;
        d[1]=0;
        priority_queue< pii , vector<pii> ,greater<pii> > Q;
        Q.push(mp(0,1));
        while(!Q.empty()){
            pii p =Q.top();Q.pop();
            int v= p.se;int val =p.fi;
            if(val>d[v])continue;
            for(int i=0;i<V[v].size();++i){
                node e= V[v][i];
                int u = e.to;
                if(d[u] > d[v]+e.cost){
                    d[u] = d[v]+e.cost;   Q.push(mp(d[u],u));
                }
            }
    
        }
    
    }
    
    int main(){
    
        int t;
        cin>>t;
        int cnt=1;
    
        while(t--){
            scanf("%d %d %d",&n,&m,&c);
            for(int i=1;i<=n*3;++i)V[i].clear();
    
            for(int i=1;i<=n;++i){
                int l;
                scanf("%d",&l);
                add(i,n+2*l-1,0);
                add(n+2*l,i,0);
            }
    
            for(int i=1;i<n;++i){
                add( n+2*i-1,n+2*(i+1),c );
                add(n +2*(i+1)-1 , n+2*i,c);
            }
            while(m--){
                int u,v,d;
                scanf("%d %d %d",&u,&v,&d);
                add(u,v,d);
                add(v,u,d);
            }
    
            n*=3;
    
            dij();
    
            n/=3;
    
            printf("Case #%d: ",cnt++);
            if(d[n]==INF)printf("-1
    ");
            else cout<<d[n]<<endl;
        }
    
        return 0;
    }
  • 相关阅读:
    [LeetCode]Reverse Linked List II
    [LeetCode]Move Zeroes
    Next Greater Element I
    Keyboard Row
    Number Complement
    SQL语句学习(二)
    SQL语句学习(一)
    jQuery学习(三)
    jQuery学习(二)
    JQuery学习(一)
  • 原文地址:https://www.cnblogs.com/wjhstudy/p/9757001.html
Copyright © 2020-2023  润新知