[USACO06NOV]路障Roadblocks

题目链接:路障

思路

  1. 次短路,顾名思义就是比当前最短路小的”最短路“,因此还是需要求出最短路
  2. 显而易见,次短路便是基于最短路的一种拓展
  3. 现在来分析一下次短路应具有的特点
    1. 小于最短路(以此得出当Dis[u]+E[i].dis==Dis[v]时,不能进行次短路更新,否则会导致次短路等于最短路)
    2. 大于其他路(因此,次短路只可能是从最短路Dis[u]或次短路Ans[u],到达v的)
    3. 如果有新最短路,则原最短路为新次短路

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int Max_N=5010,Max_M=1e5+7,inf=2147432637;
typedef pair<int,int>node;
struct Edge
{
    int next,dis,to;
} E[Max_M*2];//注意是无向图
int Head[Max_N],num_Edge,Dis[Max_N],vis[Max_N],Ans[Max_N];
int N,M;
inline int Read(void)//快读 
{
    int w=0,x=0;
    char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    return w?-x:x;

}
inline void Add_Edge(int from,int to,int dis)//建边 
{
    E[++num_Edge].dis=dis;
    E[num_Edge].next =Head[from];
    E[num_Edge].to =to;
    Head[from]=num_Edge;
}
inline void Dijkstra()
{
    queue<int>Q;
    for(int i=1; i<=N; ++i) Dis[i]=inf,Ans[i]=inf;//初始化,注意也要对次短路进行初始化 
    Dis[1]=0;
    Q.push(1) ;
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop() ;
        vis[u]=0;
        for(int i=Head[u]; i; i=E[i].next )
        {
            int v=E[i].to;
            if(Dis[v]>Dis[u]+E[i].dis )//如果找到新的最短路 
            {
                Ans[v]=Dis[v];//更新次小最短路
                Dis[v]=Dis[u]+E[i].dis ;
                if(!vis[v])
                {
                    vis[v]=1;
                    Q.push(v) ;
                }
            }
            else if(Ans[v]>Dis[u]+E[i].dis&&Dis[u]+E[i].dis!=Dis[v])//如果当前路径比最短路大,且小于次短路,则更新次短路 
            {
                Ans[v]=Dis[u]+E[i].dis ;//如果当前路径比次小最短路短,则更新次小最短路
                if(!vis[v])
                {
                    vis[v]=1;
                    Q.push(v) ;
                }
            }
            if(Ans[v]>Ans[u]+E[i].dis)//如果当前路径比次小最短路短,则更新次小最短路
            {
                Ans[v]=Ans[u]+E[i].dis ;//如果当前路径比次小最短路短,则更新次小最短路
                if(!vis[v])
                {
                    vis[v]=1;
                    Q.push(v) ;
                }
            }
        }
    }
}
int main(void)
{
    N=Read(),M=Read();
    for(int i=1; i<=M; ++i)
    {
        int u=Read(),v=Read(),d=Read();
        Add_Edge(u,v,d);
        Add_Edge(v,u,d);
    }
    Dijkstra();
    printf("%d",Ans[N]);
    return 0;
}

 

posted @ 2019-09-20 19:05  星空泪  阅读(228)  评论(0编辑  收藏  举报