zoukankan      html  css  js  c++  java
  • Light oj 1099

    题目大意:求次短路.

    题目思路:由于可能存在重边的情况所以不能采用邻接矩阵储存图,我用了邻接表来存图。

    由起点S到终点E的次短路可能由以下情况组成:

    1.S到v点的次短路 + v到E的距离

    2.S到v的最短路 +  v到E的距离

    对于每个节点,我们分别采用dist1[],dist2[]储存起点到该节点最短路与次短路

    次短路的更新条件应是:对于点u,在本轮松弛操作中若 当前的dist1[u]可以被更新,我们用d2来储存还未被更新的dist1[u]。

    若满足:dist2[u]>d2 && d2<dist1[u]

    则更新 dist2[u]。

    吐槽:实际数据范围 和题目描述的不太一样……要开大一点

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<math.h>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #define MAXSIZE 500005
    #define INF 0x3f3f3f3f
    #define LL long long
    
    using namespace std;
    
    int ans,n,k,a[MAXSIZE],dist1[MAXSIZE],dist2[MAXSIZE],vis[MAXSIZE];
    typedef pair<int, int>p;//p.second储存节点:u,p.frist储存s->u的当前最短距离
    
    struct node
    {
        int u;
        int v;
        int w;
        int next;
    }G[MAXSIZE];
    
    void Add(int u,int v,int w)
    {
        G[k].u=u;
        G[k].v=v;
        G[k].w=w;
        G[k].next=a[u];
        a[u]=k++;
    }
    
    void dfs()
    {
        priority_queue<p,vector<p>,greater<p> > Q;
        dist1[1]=0;
        Q.push(p(0,1));
        while(!Q.empty())
        {
            p k=Q.top();
            Q.pop();
            int u=k.second;
            int d=k.first;
            if(dist2[u] < d) //小优化:如果取出的不是最短距离就不再向下进行
               continue;
            for(int i=a[u];i!=-1;i=G[i].next)
            {
                int v=G[i].v;
                int d2=d+G[i].w;
                if(dist1[v] > d2) //更新最短路
                {
                    swap(dist1[v],d2);
                    Q.push(p(dist1[v],v));
                }
                if(dist2[v] > d2 && dist1[v]<d2)//更新次短路
                {
                    dist2[v]=d2;
                    Q.push(p(dist2[v],v));
                }
            }
        }
        ans=dist2[n];
    }
    
    void Init()
    {
        for(int i=0;i<MAXSIZE;i++)
        {
            dist1[i]=INF;
            dist2[i]=INF;
            vis[i]=0;
            a[i]=-1;
        }
        k=1;
    }
    
    int main()
    {
        int T,cns=1,u,v,w,m;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            Init();
            while(m--)
            {
                scanf("%d%d%d",&u,&v,&w);
                Add(u,v,w);
                Add(v,u,w);
            }
            dfs();
            printf("Case %d: %d
    ",cns++,ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    FZU Monthly-201906 tutorial
    FZU Monthly-201906 获奖名单
    FZU Monthly-201905 tutorial
    BZOJ1009 GT考试
    BZOJ2428 均分数据
    模拟退火
    BZOJ3680 吊打XXX
    BZOJ4818 序列计数
    BZOJ4103 异或运算
    BZOJ3512 DZY Loves Math IV
  • 原文地址:https://www.cnblogs.com/alan-W/p/6756831.html
Copyright © 2011-2022 走看看