zoukankan      html  css  js  c++  java
  • POJ

    题意:给你无向带权图,求次短路径

    题解:加一个次短路的数组,用于距记录源点到此点的次短路长度,注意初始化是源点到自己的次短路是极大值

       接着再使用dijkstra算法,它是每次选用现在连上(记录了)的点与其他点的最小权值的边去更新其他所有的点

       就是在dij的算法上进行简单的修改,需要修改的是每次最短路更新之后再更新次短路,但是保证更新的次短路大于记录的次短路并小于记录的最短路

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    const int inf=1<<29;
    const int maxn=200010;
    struct Edge
    {
        int v,val;
        Edge(int v,int val):v(v),val(val) {}
        bool operator < (const Edge &c)const//改写大顶堆成为小顶堆
        {
            return val>c.val;
        }
    };
    vector<Edge> vec[maxn];
    int dis[maxn],secondis[maxn];//记录第二短路径
    void init(int n)
    {
        for(int i=0; i<=n; ++i)
        {
            vec[i].clear();
        }
    }
    void dijkstraSecond(int n,int s)
    {
        priority_queue<Edge> pque;
        for(int i=0; i<=n; ++i)
        {
            dis[i]=inf;
            secondis[i]=inf;//注意初始化
        }
        //secondis[s]=0;//不能初始化
        dis[s]=0;
        pque.push(Edge(s,0));
        while(!pque.empty())
        {
            Edge disE=pque.top();
            pque.pop();
            if(secondis[disE.v]<disE.val)//注意次短路都失败了才不能加上这条路
                continue;
            for(int i=0; i<vec[disE.v].size(); ++i)
            {
                Edge endE=vec[disE.v][i];
                int disnow=disE.val+endE.val;//注意这儿不能用dis求
                if(dis[endE.v]>disnow)//松弛最短路
                {
                    swap(dis[endE.v],disnow);//由于松弛次短路,所以这儿是交换两者
                    pque.push(Edge(endE.v,dis[endE.v]));
                }
                if(secondis[endE.v]>disnow&&dis[endE.v]<disnow)//松弛次短路
                {
                    secondis[endE.v]=disnow;
                    pque.push(Edge(endE.v,secondis[endE.v]));
                }
            }
        }
    }
    int main()
    {
        int n,m;
        while(~scanf("%d %d",&n,&m))
        {
            init(n);
            while(m--)
            {
                int u,v,c;
                scanf("%d %d %d",&u,&v,&c);
                vec[u].push_back(Edge(v,c));
                vec[v].push_back(Edge(u,c));
            }
            dijkstraSecond(n,1);
    //        for(int i=1; i<=n; ++i)
    //        {
    //            printf("secondis[i]=%d
    ",secondis[i]);
    //        }
            printf("%d
    ",secondis[n]);
        }
        return 0;
    }
  • 相关阅读:
    微信小程序订阅消息
    自动生成小学四则运算题目
    个人项目作业
    自我介绍+软工5问
    软件工程之获小黄衫感言
    2020软件工程个人作业06——软件工程实践总结作业
    2020软件工程作业05
    2020软件工程作业00——问题清单
    2020软件工程作业04
    2020软件工程作业03
  • 原文地址:https://www.cnblogs.com/zhuanzhuruyi/p/6815337.html
Copyright © 2011-2022 走看看