zoukankan      html  css  js  c++  java
  • hdu4725 The Shortest Path in Nya Graph

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4725

    题目意思:有n个层n个点,每个点只属于一个层,一个层可以有多个点(这点很坑)。点通往相邻的层上的点有代价c。有额外m条带权无向路,求点1到点n的最短路。

    思路:主要是建图,建完图用spfa/dijkstra跑一边就是了。开始我用vector存每层的信息,相邻层的点相连,最后超时了。。。

    所以不能单独用点与点相连。我们可以将层抽象成一个点,利用层的间接关系来达到点相连的目的。那么我们要连接的有:点 和 上一层抽象成的点,点和下一层抽象成的点,本层抽象成的点和该点即可。

      为什么不连接该点与本层的关系呢?因为一层不只一个点,连接了会导致本层的点相互距离为0。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+10;
    struct node{
        int v,w,next;
    }edge[maxn*4];
    int head[maxn*4],visit[maxn],d[maxn];
    int n,m,c,t,cnt;
    
    void init(){//初始化 
        memset(head,-1,sizeof(head));
        memset(visit,0,sizeof(visit));
        memset(d,0x3f,sizeof(d));
        cnt=0;
    }
    
    void add(int u,int v,int w){//前向星连边 
        edge[cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    void spfa(){//spfa求最短路模板 
        queue<int >q;
        q.push(1);
        visit[1]=1;
        d[1]=0;
        while(!q.empty()){
            int t=q.front();
            q.pop();
            visit[t]=0;
            for(int i=head[t];i!=-1;i=edge[i].next){
                int v=edge[i].v;
                int w=edge[i].w;
                if(d[v]>d[t]+w){
                    d[v]=d[t]+w;
                    if(!visit[v]){
                        visit[v]=1;
                        q.push(v);
                    }
                } 
            }
        }
    }
    
    int main(){
        scanf("%d",&t);
        int k=0;
        while(t--){
            init();
            int x,u,v,w;
            scanf("%d%d%d",&n,&m,&c);
            for(int i=1;i<=n;i++){
                scanf("%d",&x);
                add(x+n,i,0);//连接本层与点 
                if(x>1)    
                    add(i,x+n-1,c);//点与上一层 
                if(x<n)
                    add(i,x+n+1,c);//点与下一层 
            }
            
            for(int i=1;i<=m;i++){//额外点与点相连 
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);
                add(v,u,w);
            }
            spfa();
            if(d[n]>=inf||n<=0)
                printf("Case #%d: -1
    ",++k);
            else
                printf("Case #%d: %d
    ",++k,d[n]);
        } 
        return 0;
    }
  • 相关阅读:
    bzoj1797
    bzoj1266
    bzoj1497
    bzoj1412
    bzoj3156
    JSOI2014第三轮总结
    bzoj1855
    bzoj1044
    codeforces 371D
    codeforces 371B
  • 原文地址:https://www.cnblogs.com/xiongtao/p/10295844.html
Copyright © 2011-2022 走看看