zoukankan      html  css  js  c++  java
  • luogu P2829 大逃离

    题目背景

    zrz走进了一个奇葩的迷宫,他发现自己迷路了,想逃出来,他好不容易数完了所有的路,累的快晕了,只好叫你帮忙咯。

    题目描述

    这是一棵有n个节点的图,有m条双向边,每一条路有w个单位距离,zrz在1的位置,出口在n的位置,不过zrz脑子出了点bug,于是不想走最短的路,想走第2短的路,第2短路径允许与最短路径有重边,然后也可以重复通过一些节点和路,注意如果有多条路径都是最短路径,那么他们都不能叫第2短路径。但是zrz觉得如果接下来进入的一个节点所直接连接的地方小于k个(起点和终点除外),那么他就不敢进去。

    输入输出格式

    输入格式:

     

    第一行3个数:n,m,k

    接下来m行:每行3个数,u,v,w。表示从u到v有一条权值为w的边。(u,v<=n,w<=10000)

     

    输出格式:

     

    一个数:表示从s走到t的第2短路的值,如果不存在,输出-1

     

    输入输出样例

    输入样例#1: 复制
    4 4 1
    1 2 100
    2 4 200
    2 3 250
    3 4 100
    输出样例#1: 复制
    450
    输入样例#2: 复制
    4 4 3
    1 2 100
    2 4 200
    2 3 250
    3 4 100
    输出样例#2: 复制
    500

    说明

    对于50%的数据:n<=10,m<=10

    对于90%的数据:n<=1000,m<=20000

    对于100%的数据:n<=5000,m<=100000

    另外,k比较小

    样例2最短路径是300(1-2-4)。因为从2无法走到3(3连接到的节点只有2个),所以可以1-2-1-2-4,第二短路为500。

    题目链接:https://www.luogu.org/problemnew/show/2829

    解题报告:

    SPFA求次短路,松弛操作.

    AC代码

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<queue>
    #define INF (1<<30)
    #define ll long long
    #define BIG 200011
    using namespace std;
    queue<int>q;
    int x,y,z,tot,cnt;
    int n,m,k,d1[BIG],d2[BIG],inq[BIG];
    int nxt[BIG],las[BIG],to[BIG],w[BIG],deg[BIG];
    #define FOR(s,t) for(register int i=s;i<=t;++i)
    #define VIS(now) for(register int e=las[now];e;e=nxt[e])
    inline void add(int x,int y,int z){
        nxt[++tot]=las[x],las[x]=tot,to[tot]=y,w[tot]=z;
    }
    inline void SPFA(){
        FOR(2,n)d1[i]=d2[i]=INF;
        d2[1]=INF;
        q.push(1);
        inq[1]=1;
        int u,v;
        while(!q.empty()){
            u=q.front();q.pop();
            inq[u]=0;
            VIS(u){
                v=to[e];
                if(v!=n&&v!=1&deg[v]<k)continue;
                if(d1[v]>=d1[u]+w[e]){
                    d2[v]=min(d2[v],d2[u]+w[e]),d1[v]=d1[u]+w[e];
                    if(!inq[v])q.push(v),inq[v]=1;
                }
                else
                    if(d2[v]>d1[u]+w[e]){
                        d2[v]=d1[u]+w[e];
                        if(!inq[v])q.push(v),inq[v]=1;
                    }
            }
        }
    }
    int main(){
        scanf("%d%d%d",&n,&m,&k);
        while(m--){
            scanf("%d%d%d",&x,&y,&z);
            add(y,x,z),add(x,y,z);
        }
        FOR(2,n-1){
        	VIS(i)
        		if(!inq[to[e]])inq[to[e]]=1,++deg[i];
        	VIS(i)
        		inq[to[e]]=0;
    	}
        SPFA();
        printf("%d
    ",d2[n]<INF?d2[n]:(-1));
        return 0;
    }
    

      

  • 相关阅读:
    3d max 动作Take 001改名
    Lua代码规范
    Unity Editor 下创建Lua和Text文件
    Unity 5 Stats窗口
    Unity与安卓开发的一些路径知识
    Unity Remote 无法连接
    常见胸肌问题解答(五):下缘不够清晰
    常见胸肌问题解答(四):胸肌块形不够宽
    杠铃卧推:平板、上斜、下斜杠铃卧推动作图解教程
    常见胸肌问题解答(二):上胸不够发达
  • 原文地址:https://www.cnblogs.com/Stump/p/7751653.html
Copyright © 2011-2022 走看看