其他分享
首页 > 其他分享> > bzoj1726: [Usaco2006 Nov]Roadblocks第二短路

bzoj1726: [Usaco2006 Nov]Roadblocks第二短路

作者:互联网

【题目大意】

求无向图点1到n的次短路。

【思路】

堆优化Dijkstra,方法就是一边跑Dijsktra一边就把次短路径保存下来。和一般Dijkstra不同的是把vis数组去掉了,因为还要生成次短路径。

 

重新写用的是SPFA。正反跑两次SPFA,然后枚举每一条边,如果起点到一个端点的最短路+另一个端点到终点的最短路+长度 ≠ 最短路,则和答案比较,保存最小值。还是很好理解的

#include<bits/stdc++.h>
using namespace std;
const int MAXR=1e5+5;
const int MAXN=5e3+5;
const int INF=21e8;
struct edge
{
    int to,len;
};
vector<edge> E[MAXN];
int n,r,dis[MAXN],inque[MAXN],dis1[MAXN],dis2[MAXN];
int u[MAXR],v[MAXR],w[MAXR];
void addedge(int u,int v,int w)
{
    E[u].push_back((edge){v,w});
    E[v].push_back((edge){u,w});
}
void spfa(int S,int T)
{
    for (int i=1;i<=n;i++) inque[i]=0,dis[i]=INF;
    queue<int> que;
    que.push(S);
    inque[S]=1;dis[S]=0;
    while (!que.empty())
    {
        int head=que.front();que.pop();
        inque[head]=0;
        for (int i=0;i<E[head].size();i++)
        {
            int nowdis=dis[head]+E[head][i].len,to=E[head][i].to;
            if (nowdis<dis[to])
            {
                dis[to]=nowdis;
                if (!inque[to])
                {
                    que.push(to);
                    inque[to]=1;
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&r);
    for (int i=1;i<=r;i++)
    {
        scanf("%d%d%d",&u[i],&v[i],&w[i]);
        addedge(u[i],v[i],w[i]);
    }
    spfa(1,n);
    for (int i=1;i<=n;i++) dis1[i]=dis[i];
    spfa(n,1);
    for (int i=1;i<=n;i++) dis2 [i]=dis[i];
    int mx=dis1[n],ans=INF;
    for (int i=1;i<=r;i++)
    {
        int now=dis1[u[i]]+dis2[v[i]]+w[i];
        if (now!=mx) ans=min(ans,now);
        now=dis1[v[i]]+dis2[u[i]]+w[i];
        if (now!=mx) ans=min(ans,now);
    }
    printf("%d",ans);
    return 0;    
}

 

标签:int,短路,MAXR,Roadblocks,edge,que,MAXN,Nov,bzoj1726
来源: https://www.cnblogs.com/zzrblogs/p/10458390.html