zoukankan      html  css  js  c++  java
  • Dijkstra求次短路

    #10076.「一本通 3.2 练习 2」Roadblocks:https://loj.ac/problem/10076

    解法:

      次短路具有一种性质:次短路一定是由起点到点x的最短路 + x到y的距离 + y到终点的最短路构成,且次短路的权值和严格大于最短路的权值和。

      我们可以从起点跑一次Dijkstra,再从终点跑一次Dijkstra,这样起点到每个点的最短距离以及终点到每个点的最短距离都已经确定了,

      接着枚举每一个节点u,再枚举从该点从发的每一条边v,更新答案就可以了。

      最后由于题目中的边可以重复走,所以把(u,v)的边权*3倍也计算进去就可以了。

    #include<bits/stdc++.h>
    using namespace std;
    #define re register int
    #define ll long long
    #define INF 0x3f3f3f3f
    #define maxn 5009
    #define maxm 100009
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ll)(ch-'0');ch=getchar();}
        return x*f;
    }
    int head[maxn],dis[maxn],dist[maxn];
    //dist 1->n的最短路 dis n->1的最短路 
    bool vis[maxn];
    struct edge
    {
        int to,nxt,val;
    }p[maxm<<1];
    int n,m,k,ans,tot,cnt,mx,sum; 
    
    void add(int x,int y,int z)
    {
        ++cnt,p[cnt].to=y,p[cnt].nxt=head[x],p[cnt].val=z,head[x]=cnt;
    }
    void Dijkstra(int x)
    {
        memset(dis,INF,sizeof(dis));
        memset(vis,0,sizeof(vis));
        priority_queue<pair<int,int> >q;
        dis[x]=0;
        q.push(make_pair(0,x));
        while(q.size())
        {
            int u=q.top().second;q.pop();
            if(vis[u])
                continue;
            vis[u]=1;
            for(int i=head[u];i;i=p[i].nxt)
            {
                int v=p[i].to;    
                if(dis[v]>dis[u]+p[i].val)
                {            
                    dis[v]=dis[u]+p[i].val;
                    q.push(make_pair(-dis[v],v));
                }
            }
        }
    }
    int main()
    {
    //    freopen(".in","r",stdin);
    //    freopen(".out","w",stdout);
        n=read(),m=read();
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read(),z=read();
            add(x,y,z),add(y,x,z);
        }
        Dijkstra(1);
        for(int i=1;i<=n;i++)
            dist[i]=dis[i];
        Dijkstra(n);
    /*    for(int i=1;i<=n;i++)
            cout<<dist[i]<<" ";
        cout<<endl;
        for(int i=1;i<=n;i++)
            cout<<dis[i]<<" ";
        cout<<endl;*/
        ans=INF;
        for(int u=1;u<=n;u++)
        {
            for(int i=head[u];i;i=p[i].nxt)
            {
                int v=p[i].to;
                int diss=dist[u]+p[i].val+dis[v];
                if(diss<ans&&diss>dist[n])
                    ans=diss;
                diss+=p[i].val*2;
                if(diss<ans&&diss>dist[n])
                    ans=diss;
            }
        }
        printf("%d
    ",ans);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }

     

  • 相关阅读:
    程序设计思维与实践 Week5 作业 (3/4/数据班)
    程序设计思维与实践 Week6 作业 (3/4/数据班)
    Effective C++笔记(更新中...)
    二叉树的序列化与反序列化
    矩阵乘法的顺序安排问题 Python简单实现
    Python 读写Excel文件 总结
    2019美赛D题 人员疏散模型Python编程
    函数绘图语言 西电编译原理大作业
    洛谷试炼场 动态规划专练
    2019 IEEEXtreme 13.0 Impact Factor 影响因子
  • 原文地址:https://www.cnblogs.com/Dxy0310/p/9779289.html
Copyright © 2011-2022 走看看