zoukankan      html  css  js  c++  java
  • HDU 4725 The Shortest Path in Nya Graph(优先队列+dijkstra)

    题意:n个点、m条边、层与层之间的花费为c,给出每个点所在层(同一层的点联通花费为0),m条边每条边的花费,求1到n的最小花费;

    思路:第一反应就是优先队列的dijkstra,层与层之间建边,点与点之间建边,层与包含点之间建边,点与相邻层之间建边;练习一下优先队列dijkstra和邻接表;

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define INF 0x3f3f3f3f
    int pp[500010],vv[500010],dist[500010];
    int vis[500010],cnt,n,m,c;
    int lay[500010];
    struct Node
    {
        int u,v,w;
        int next;
    }edge[500010];//邻接表
    struct node
    {
        int pos,dd;
        bool operator <(const node&xx)const
        {
            return dd>xx.dd;
        }
    }cur,now;
    void addedge(int u,int v,int w)//邻接表
    {
        cnt++;
        edge[cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].next=pp[u];
        pp[u]=cnt;
    }
    priority_queue<node> q;
    void dijkstra()
    {
        int i,j,k,u,v,w;
        memset(vis,0,sizeof(vis));
        while(!q.empty()) q.pop();
        dist[1]=0;
        cur.pos=1;cur.dd=0;
        q.push(cur);
        while(!q.empty())
        {
            now=q.top();
            q.pop();
            u=now.pos;
            if(vis[u]) continue;
            vis[u]=1;
            for(i=pp[u];i;i=edge[i].next)
            {
                v=edge[i].v;
                w=edge[i].w;
                if(!vis[v]&&dist[v]>dist[u]+w)
                {
                    dist[v]=dist[u]+w;
                    cur.pos=v;cur.dd=dist[v];
                    q.push(cur);
                }
            }
        }
    }
    int main()
    {
        int i,j,k,u,v,w,t,temp;
        scanf("%d",&t);
        for(k=1;k<=t;k++)
        {
            scanf("%d%d%d",&n,&m,&c);
            memset(pp,0,sizeof(pp));
            memset(vv,0,sizeof(vv));
            memset(dist,INF,sizeof(dist));
            cnt=0;
            for(i=1;i<=n;i++)
            {
                scanf("%d",&u);
                lay[i]=u;
                vv[u]=1;
            }
            for(i=1;i<n;i++)
            {
                if(vv[i]&&vv[i+1])//相邻层之间建边
                {
                    addedge(n+i,n+i+1,c);//使用n个点以外的编号
                    addedge(n+i+1,n+i,c);
                }
            }
            for(i=1;i<=n;i++)
            {
                addedge(lay[i]+n,i,0);//层与所包含点建边
                if(lay[i]>1) addedge(i,lay[i]+n-1,c);//点与相邻层建边
                if(lay[i]<n) addedge(i,lay[i]+n+1,c);//点与相邻层建边
            }
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);//点与点之间建边
                addedge(u,v,w);
                addedge(v,u,w);
            }
            dijkstra();
            temp=dist[n];
            printf("Case #%d: ",k);
            if(temp==INF) printf("-1
    ");
            else printf("%d
    ",temp);
        }
        return 0;
    }
    

      

  • 相关阅读:
    CentOS 6.5 伪分布式 安装 hadoop 2.6.0
    单例模式的思想简介
    最有二叉树 哈夫曼树
    二叉树2
    二叉树1
    栈与队列
    线性表
    字符串模式匹配KMP算法
    数据结构(四) 查找 排序
    数据结构(三) 图
  • 原文地址:https://www.cnblogs.com/dashuzhilin/p/4451635.html
Copyright © 2011-2022 走看看