• HDU 4725 The Shortest Path in Nya Graph(最短路建边)题解


    题意:给你n个点,m条无向边,每个点都属于一个层,相邻层的任意点都能花费C到另一层任意点,问你1到n最小路径

    思路:没理解题意,以为每一层一个点,题目给的是第i个点的层数编号。这道题的难点在于建边,如果用最朴素的相邻层所有点互相连接,那么可能有5*10^4连5*10^4,复杂度O(n^2)。这里我们用拆点(?大概),把每一层拆出一个点,作为每一层点和相邻层连接的中转站。这里要特别注意,同一层的点的距离不是0,所以我们建边不能全是无向边:

    1.层与层无向边,权值C

    2.层与同层点建单向边,权值0

    2.点与相邻层单向边,权值C

    这样,每个点都能通过每层拆出的点连接相邻层的点,而且同层的点的距离不为0。然而写完这些后我又TLE了...orz,把建边的vector邻接表改成手动建边,358ms过

    代码:

    #include<cstdio>
    #include<set>
    #include<cmath>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn = 200000+5;
    const int INF = 0x3f3f3f3f;
    struct Edge{
        int v,w,next;
    }edge[20*maxn];
    bool vis[maxn];
    int dis[maxn],head[maxn],tot;
    void spfa(int start){
        memset(vis,false,sizeof(vis));
        memset(dis,INF,sizeof(dis));
        vis[start] = true;
        dis[start] = 0;
        queue<int> q;
        while(!q.empty()) q.pop();
        q.push(start);
        while(!q.empty()){
            int u = q.front();
            q.pop();
            vis[u] = false;
            for(int i = head[u];i != -1;i = edge[i].next){
                int v = edge[i].v;
                int w = edge[i].w;
                if(dis[v] > dis[u] + w){
                    dis[v] = dis[u] + w;
                    if(!vis[v]){
                        q.push(v);
                        vis[v] = true;
                    }
                }
            }
        }
    }
    void addEdge(int u,int v,int w){
        edge[tot].v = v;
        edge[tot].w = w;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    int layer[maxn];
    bool have[maxn];
    int main(){
        int T;
        int n,m,C,Case = 1;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d%d",&n,&m,&C);
            tot = 0;
            memset(head,-1,sizeof(head));
            memset(have,false,sizeof(have));
            for(int i =  1;i <= n;i++){
                scanf("%d",&layer[i]);
                have[layer[i]] = true;
            }
            for(int i = 1;i < n;i++){   //层层建边
                if(have[i] && have[i + 1]){
                    addEdge(n + i,n + i + 1,C);
                    addEdge(n + i + 1,n + i,C);
                }
            }
            for(int i = 1;i <= n;i++){  //层点建边 相邻层点建边
                addEdge(n + layer[i],i,0);
                if(layer[i] > 1)
                    addEdge(i,n + layer[i] - 1,C);
                if(layer[i] < n)
                    addEdge(i,n + layer[i] + 1,C);
            }
            while(m--){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                addEdge(u,v,w);
                addEdge(v,u,w);
            }
            spfa(1);
            if(dis[n] == INF){
                printf("Case #%d: -1
    ",Case++);
            }
            else{
                printf("Case #%d: %d
    ",Case++,dis[n]);
            }
        }
        return 0;
    }
  • 相关阅读:
    索引聚焦如何使 SQL Server高效 设计(ITPUT 讨论汇总)
    android包Android "java.lang.NoClassDefFoundError:*"报错的处理方法
    删除实现图的构造、DFS、BFS 以及图的删除实现
    RTL8019以太网控制器
    JavaScript正则表达式
    sql语句
    无线模块电阻表
    FindWindow(api)确认程序是否在运行
    正则表达式语法
    msi安装程序安装参数
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9480439.html
Copyright © 2020-2023  润新知