• The Shortest Path in Nya Graph HDU


    题目描述

    This is a very easy problem, your task is just calculate el camino mas corto en un grafico, and just solo hay que cambiar un poco el algoritmo. If you do not understand a word of this paragraph, just move on.
    The Nya graph is an undirected graph with "layers". Each node in the graph belongs to a layer, there are N nodes in total.
    You can move from any node in layer x to any node in layer x + 1, with cost C, since the roads are bi-directional, moving from layer x + 1 to layer x is also allowed with the same cost.
    Besides, there are M extra edges, each connecting a pair of node u and v, with cost w.
    Help us calculate the shortest path from node 1 to node N.

    Input

    The first line has a number T (T <= 20) , indicating the number of test cases.
    For each test case, first line has three numbers N, M (0 <= N, M <= 10 5) and C(1 <= C <= 10 3), which is the number of nodes, the number of extra edges and cost of moving between adjacent layers.
    The second line has N numbers l i (1 <= l i <= N), which is the layer of i th node belong to.
    Then come N lines each with 3 numbers, u, v (1 <= u, v < =N, u <> v) and w (1 <= w <= 10 4), which means there is an extra edge, connecting a pair of node u and v, with cost w.

    Output

    For test case X, output "Case #X: " first, then output the minimum cost moving from node 1 to node N.
    If there are no solutions, output -1.

    题目大意: 给你n个点,这n个点分别属于某一个层,在同一个层中所有点相互之间的距离为0,对于在 x 层中的所有点,其通向 第 x-1 层 和第 x+1 层的点都有一条双向道路,且权值为 c 。再给你一些双向道路。问你从点1到点n的最短距离是多少。

    解题思路:   首先这题的难点就在于建图,因为最多会给你1e5个点,如果对每层中的每个点都按常规方法建图,一定会t。         

                       建图方法如下

                        

                       这种建图方式大大减少了边的总数,边的总数大概从N*N 变成了 5N+2N 条 ,点的总数变成了 2N。

    代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long 
    #define MOD 998244353 
    #define INF 0x3f3f3f3f
    #define mem(a,x) memset(a,x,sizeof(a))  
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    const int NUM = 200005;
    const int maxn = 200005;
    struct node{
       int to,w;
       node(int b,int c){to=b;w=c;}
    };
    vector<node>e[NUM];
    int dis[NUM];
    bool vis[NUM];
    int n,m,c;
    int l[200005];
    int a[200005];
    struct cmp
    {
       bool operator()(int a,int b)
       {
          return dis[a]>dis[b];
       }
    };
    void Dijkstra()
    {
        priority_queue<int,vector<int>,cmp>Q;
        for(int i=0;i<=maxn;i++){
            dis[i]=INF;
            vis[i]=false;
        }
        dis[1]=0;
        Q.push(1);
        while(!Q.empty()){
            int u=Q.top();
            Q.pop();
            if(vis[u])continue;
            vis[u]=1;
            for(int i=0;i<e[u].size();i++){
                int v=e[u][i].to;
                int w=e[u][i].w;
                if(dis[v]>dis[u]+w){
                    dis[v]=dis[u]+w;
                    Q.push(v);
                }
            } 
        }
    }
    int main()
    {
        int t,tt;
        cin>>t;
        tt=t;
        while(t--){
            for(int i=1;i<=maxn;i++){
                a[i]=0;
                l[i]=0;
                e[i].clear();
            }
            scanf("%d %d %d",&n,&m,&c);
            for(int i=1;i<=n;i++){
              scanf("%d",&l[i]);
              a[l[i]]=1;
            }
            //分层建图
            for(int i=1;i<=n;i++){
                e[l[i]+n].push_back(node(i,0));
                if(a[l[i]-1]){
                   e[i].push_back(node(l[i]+n-1,c));
                }
                if(a[l[i]+1]){
                   e[i].push_back(node(l[i]+n+1,c));
                }
            }
            for(int i=1;i<=m;i++){
                int a,b,d;
                scanf("%d %d %d",&a,&b,&d);
                e[a].push_back(node(b,d));
                e[b].push_back(node(a,d));
            }
            Dijkstra();
            if(dis[n]<INF){
                printf("Case #%d: %d
    ",tt-t,dis[n]);
            }else{
                printf("Case #%d: -1
    ",tt-t);
            }
    
            
        }
        return 0;
    }
    越自律,越自由
  • 相关阅读:
    单表查询
    解读python中SocketServer源码
    C++实训(2.3)
    C++实训(2.2)
    C++实训(2.1)
    C++实训(1.3)
    C++实训(1.1)
    顺序表的实现,在vs2019上运行成功
    p243_5(3)
    自考新教材-p176_5(2)
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/13435566.html
Copyright © 2020-2023  润新知