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;
    }
    




  • 相关阅读:
    win10 uwp 读取保存WriteableBitmap 、BitmapImage
    win10 uwp 读取保存WriteableBitmap 、BitmapImage
    win10 uwp 按下等待按钮
    win10 uwp 按下等待按钮
    win10 uwp 右击选择 GridViewItem
    win10 uwp 右击选择 GridViewItem
    PHP array_column() 函数
    PHP array_chunk() 函数
    PHP array_change_key_case() 函数
    PHP array() 函数
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777546.html
Copyright © 2011-2022 走看看