• HDU 4725(最短路+思维建图)


    题意:T组输入。n,m,c代表n个点,m个关系,相邻两层移动距离为C。每个点都会存在某一层上。

      一个点可以移动c到相邻的层上任意一点(不能移动c到同一层的一点上)。

    问:第一个点到第n个点的最短路

    思路:把每层看做其他的新加的点,第一层可以看作第n+1个点。

     -------------------------------------------------------------------------

    我刚开始写的时候。

    错解:第一层的所有点和第n+1个点建了双向,且权值为零的路。这样是错的,因为如果这样建图,同一层的点互相达到的距离为0.

    正解:由第n+1个点到第一层的所有点建个单向的路,再由第一层的各个点建个单向的路到第一层相邻的两个层(就是第零层和第二层,实际上没有第零层,举个例子而已,k层的两边是n+k+1和n+k-1)的路,如果这层不存在就不需要建路。

    注意第1层和第n层要特殊判断一下。

    最短路跑完后如果d[n]==inf,侧代表无路

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <iomanip>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <set>
    #include <vector>
    //const int maxn = 1e5+5;
    #define ll long long
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    #define inf 0x3f3f3f3f
    #define MAX INT_MAX
    #define FOR(i,a,b) for( int i = a;i <= b;++i)
    #define bug cout<<"--------------"<<endl
    using namespace std;
    int n,c,m,tot;
    int ver[550000],edge[550000],Next[550000],head[550000],d[550000],val[550000],vis[550000];
    void add(int x,int y,int z)
    {
        ver[++tot] = y,edge[tot] = z;
        Next[tot] = head[x],head[x] = tot;
    }
    void dijkstra()
    {
        priority_queue<pair<int,int> >que;
        memset(d,inf,sizeof(d));
        memset(vis,0,sizeof(vis));
        d[1] = 0;
        que.push(make_pair(0,1));
        while(que.size())
        {
            int x = que.top().second;que.pop();
            if(vis[x] == 1) continue;
            vis[x] = 1;
            for(int i= head[x];i;i=Next[i])
            {
                int y = ver[i],z = edge[i];
                if(d[y] > d[x] + z)
                {
                    d[y] = d[x] + z;
                    que.push(make_pair(-d[y],y));
                }
            }
        }
    }
    void clearr()
    {
        tot = 0;
        memset(head,0,sizeof(head));
        memset(val,0,sizeof(val));
        memset(vis,0,sizeof(vis));
    }
    int main()
    {
    
        //  ios::sync_with_stdio(false);
        int T,casee = 0;
        scanf("%d",&T);
        while(T--)
        {
            clearr();
            scanf("%d %d %d",&n,&m,&c);
            for(int i=1;i<=n;++i)
            {
                int ceng;
                scanf("%d",&ceng);
                vis[ceng] = 1;
                val[i] = ceng;
            }
            for(int i=1;i<=m;++i)
            {
                int x,y,z;
                scanf("%d %d %d",&x,&y,&z);
                add(x,y,z);
                add(y,x,z);
            }
            for(int i=1;i<=n;++i)
            {
                if(val[i] == 1)
                {
                    add(val[i]+n,i,0);
                    if(vis[val[i]+1] == 1 )
                    {
                        add(i,val[i]+n+1,c);
                    }
                }
                else if(val[i] == n)
                {
                    add(val[i]+n,i,0);
                    if(vis[val[i]-1] == 1) 
                    {
                        add(i,val[i]+n-1,c);
                    }
                }
                else
                {
                    add(val[i]+n,i,0);
                    if(vis[val[i]+1] == 1 )
                    {
                        add(i,val[i]+n+1,c);
                    }
                    if(vis[val[i]-1] == 1 )
                    {
                        add(i,val[i]+n-1,c);
                    }
                }
            }
            dijkstra();
            if(d[n] == inf)   printf("Case #%d: -1
    ",++casee);
            else printf("Case #%d: %d
    ",++casee,d[n]);
        }
    
    
    
    }
  • 相关阅读:
    SqlParameter的作用与用法
    自制ASP.NET 本地授权文件
    教你如何谷歌浏览器免费打电话
    grep命令
    前端培训
    环境变量
    jenkins执行脚本npm: command not found解决
    Linux下给mysql创建用户并分配权限
    h5视频微信禁止全屏 x5-playsinline
    git 删除本地分支和远程分支、本地代码回滚和远程代码库回滚
  • 原文地址:https://www.cnblogs.com/jrfr/p/11372653.html
Copyright © 2020-2023  润新知