• 【BZOJ】1726 [Usaco2006 Nov]Roadblocks第二短路


    【算法】最短路(spfa) 次短路

    【题解】

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

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=5010,maxm=100010,inf=0x3f3f3f3f;
    struct edge{int u,v,w,from;}e[maxm*3];
    int n,m,first[maxn],dist[maxn],dis1[maxn],dis2[maxn],tot,q[maxn*3];
    bool vis[maxn];
    void insert(int u,int v,int w)
    {tot++;e[tot].u=u;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
    void spfa(int s)
    {
        memset(vis,0,sizeof(vis));
        memset(dist,0x3f,sizeof(dist));
        int l=1,r=1;q[1]=s;dist[s]=0;vis[s]=1;
        while(l<=r)
         {
            int x=q[l++];
            for(int i=first[x];i;i=e[i].from)
             if(dist[x]+e[i].w<dist[e[i].v])
              {
                  int y=e[i].v;
                  dist[y]=dist[x]+e[i].w;
                  if(!vis[y])
                   {
                       q[++r]=y;
                       vis[y]=1;
                   }
              }
            vis[x]=0;
         }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
         {
             int u,v,w;
             scanf("%d%d%d",&u,&v,&w);
             insert(u,v,w);
             insert(v,u,w);
         }
        spfa(1);
        for(int i=1;i<=n;i++)dis1[i]=dist[i];
        spfa(n);
        for(int i=1;i<=n;i++)dis2[i]=dist[i];
        int ans=inf;
        for(int i=1;i<=tot;i++)
         {
             int x=e[i].u,y=e[i].v;
             int now=dis1[x]+dis2[y]+e[i].w;
             if(now>dis1[n]&&now<ans)ans=now;
             now=dis1[y]+dis2[x]+e[i].w;
             if(now>dis1[n]&&now<ans)ans=now;
         }
        printf("%d",ans);
        return 0;
    }
    spfa
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int maxn=5010,maxm=200010,inf=0x3f3f3f3f;
    struct edge{int from,u,v,w;}e[maxm];
    struct Node{int x,d;}cyc;
    int n,m,first[maxn],tot,d[maxn],d_[maxn],s,t,anss,ans;
    priority_queue<Node>q;
    bool operator <(Node a,Node b)
    {return a.d>b.d;}
    void insert(int u,int v,int w)
    {tot++;e[tot].u=u;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
    void dijkstra(int* d)
    {
        for(int i=1;i<=n;i++)d[i]=inf;
        d[s]=0;
        cyc.x=s,cyc.d=d[s];q.push(cyc);
        while(!q.empty())
         {
            cyc=q.top();q.pop();
            if(cyc.d!=d[cyc.x])continue;
            int x=cyc.x;
            for(int i=first[x];i;i=e[i].from)
             if(d[e[i].v]>d[x]+e[i].w)
              {
                  d[e[i].v]=d[x]+e[i].w;
                  cyc.x=e[i].v,cyc.d=d[e[i].v];
                  q.push(cyc);
              }
         }
        anss=d[t];
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
         {
             int u,v,w;
             scanf("%d%d%d",&u,&v,&w);
             insert(u,v,w);
             insert(v,u,w);
         }
        s=1;t=n;
        dijkstra(d);
        s=n;t=1;
        dijkstra(d_);
        int ans=inf;
        for(int i=1;i<=tot;i++)
         {
             if(d[e[i].u]+e[i].w+d_[e[i].v]>anss)
              ans=min(ans,d[e[i].u]+e[i].w+d_[e[i].v]);
         }
        printf("%d",ans);
        return 0; 
    }
    dijkstra
  • 相关阅读:
    java8学习
    linux常用命令
    window操作系统分区
    java8特性
    mysql索引本质
    红黑树
    http请求传参问题解决
    老王说架构
    从URL到看到网页的过程
    RabbitMQ如何工作和RabbitMQ核心概念
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6204297.html
Copyright © 2020-2023  润新知