zoukankan      html  css  js  c++  java
  • lightoj 1099【dijkstra/BFS】

    题意:

    求 1-N 的第二长路,一条路可以重复走
    if two or more shortest paths exist, the second-shortest path is the one whose length is longer than those but no longer than any other path
    思路:
    一开始想的就是:
    我只要在spfa中更新的时候记录 dis[1][i]的最小和次小就好啦;
    其实每个权值都带一个附属权值就好了;
    这样能解决的好少,光是重复就不行了;
    正确思路:

    思想类似dijkstra 算法里:每次取最小边然后更新一波,只不过这里最小边有两种罢了;

    次短路要么从某个最短路过来,要么从某个次短路过来。对于从1过去的点,只要有被更新到最短路或者次短路,那么就要对所有的点都搞一遍,每次取最小的边,然后一直更新;
    引我南哥的小代码:
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <sstream>
    #include <cmath>
    using namespace std;
    #include <queue>
    #include <stack>
    #include <set>
    #include <vector>
    #include <deque>
    #include <map>
    #define cler(arr, val)    memset(arr, val, sizeof(arr))
    #pragma comment(linker, "/STACK:102400000,102400000")
    typedef long long  LL;
    const int MAXN = 5010+1;
    const int MAXM = 240000;
    const int INF = 0x3f3f3f3f;
    const int mod = 1000000007;
    int d[MAXN][2],head[MAXN],tol;
    bool vis[MAXN][2];
    struct node
    {
        int u,v,val,next;
    }edge[MAXM];
    void addedge(int u,int v,int w)
    {
        edge[tol].u=u,edge[tol].v=v,edge[tol].val=w,edge[tol].next=head[u];
        head[u]=tol++;
        edge[tol].u=v,edge[tol].v=u,edge[tol].val=w,edge[tol].next=head[v];
        head[v]=tol++;
    }
    void dij(int n)
    {
        for(int i=0;i<=n;i++)
            d[i][0]=d[i][1]=INF,vis[i][0]=vis[i][1]=false;
        d[0][0]=0;
        while(true)
        {
            int v=-1,k;
            int minlen=INF;
            for(int u=0;u<n;u++)
            {
                for(int l=0;l<2;l++)
                    if(!vis[u][l]&&(v==-1||d[u][l]<minlen))
                    {
                        minlen=d[u][l];
                        k=l;
                        v=u;
                    }
            }
            if(v==-1) break;
            vis[v][k]=true;
            for(int i=head[v];~i;i=edge[i].next)
            {
                int u=edge[i].v;//目标
                int cost=d[v][k]+edge[i].val;
                if(cost<d[u][0])
                {
                    d[u][1]=d[u][0];
                    d[u][0]=cost;
                }
                else if(cost<d[u][1]&&cost>d[u][0])
                {
                    d[u][1]=cost;
                }
            }
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
           freopen("in.txt", "r", stdin);
       //  freopen("out.txt", "w", stdout);
    #endif
        int t,n,m,u,v,w,cas=1;
        cin>>t;
        while(t--)
        {
            cler(head,-1);
            tol=0;
            cin>>n>>m;
            int a=0;
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                a=max(a,u);
                a=max(a,v);
                u--,v--;
                addedge(u,v,w);
            }
            dij(a);
            printf("Case %d: %d
    ",cas++,d[n-1][1]);
        }
        return 0;
    }
    




  • 相关阅读:
    net core 使用 rabbitmq
    asp.net core WebApi 返回 HttpResponseMessage
    asp.net core 2.1 WebApi 快速入门
    JQuery EasyUI combobox动态添加option
    php截取字符去掉最后一个字符
    JQuery EasyUI Combobox的onChange事件
    对于不返回任何键列信息的 selectcommand 不支持 updatecommand 的动态 sql 生成
    Access2007 操作或事件已被禁用模式阻止解决办法
    Easyui 中 Tabsr的常用方法
    Win 7 IE11不能下载文件,右键另存为也不行
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777546.html
Copyright © 2011-2022 走看看