zoukankan      html  css  js  c++  java
  • 【bzoj1726/Usaco2006 Nov】Roadblocks第二短路——SPFA

    题目链接

    分析:题目要求一个连通图的从1到n的严格次短路,我们只需要在跑最短路的时候顺便判一下次短路是否能够被更新即可。

    dis[x][0]表示1到x的最短路,而dis[x][1]则表示次短路,需要分成三类讨论:

    dis[x][0]+e[i].w<dis[to][0],此时dis[x][1]是原最短路和dis[x][1]+e[i].w的较小值(注意这里最短路要在更新完次短路后再更新);

    dis[x][0]+e[i].w>dis[to][0]&&dis[x][0]+e[i].w<dis[to][1],这条路虽然不能更新最短路,但可以更新次短路;

    dis[x][0]+e[i].w==dis[to][0],因为是严格小于,所以不能把这个值赋给次短路,应为dis[to][1]=min(dis[to][1],dis[x][1]+w[i].w)。

    另外,若这条边可以更新最短路或是次短路并且to不在队列中,再将to加入队列中。

    最最后,记得每次一个点出队后要记得把标记清为0!!!

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<algorithm>
     5 const int N=5005,inf=0x3f3f3f3f;
     6 int n,m,tot=0,first[N],q[N];
     7 struct node{
     8     int ne,to,w;
     9 }e[100000*2];
    10 int read(){
    11     int ans=0,f=1;char c=getchar();
    12     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    13     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    14     return ans*f;
    15 }
    16 int dis[N][2];
    17 bool ok[N];
    18 void add(int u,int v,int z){
    19     tot++;e[tot].ne=first[u];first[u]=tot;e[tot].to=v;e[tot].w=z;
    20     tot++;e[tot].ne=first[v];first[v]=tot;e[tot].to=u;e[tot].w=z;
    21 }
    22 int mins(int x,int y){return x>y?y:x;}
    23 void spfa(){
    24     for(int i=1;i<=n;i++)dis[i][1]=dis[i][0]=inf;
    25     dis[1][0]=0;
    26     int h=0,t=1;q[0]=1;ok[1]=1;
    27     while(h!=t){
    28         int x=q[h++];if(h>=5000)h=0;
    29         for(int i=first[x];i;i=e[i].ne){
    30             int to=e[i].to;bool ff=0;
    31             int p1=dis[x][0]+e[i].w;
    32             if(dis[to][0]>p1){
    33                 ff=1;dis[to][1]=mins(dis[to][0],dis[x][1]+e[i].w);
    34                 dis[to][0]=p1;
    35             }
    36             else if(p1>dis[to][0]&&dis[to][1]>p1)ff=1,dis[to][1]=p1;
    37             else if(dis[to][1]>dis[x][1]+e[i].w)ff=1,dis[to][1]=dis[x][1]+e[i].w;
    38             if(!ok[to]&&ff){
    39                 ok[to]=1;q[t++]=to;if(t>=5000)t=0;
    40             }
    41         }
    42         ok[x]=0;
    43     }
    44 }
    45 int main(){
    46     n=read();m=read();
    47     for(int i=1,a,b,c;i<=m;i++){
    48         a=read();b=read();c=read();
    49         add(a,b,c);
    50     }
    51     spfa();
    52     printf("%d",dis[n][1]);
    53     return 0;
    54 }
    Usaco2006
  • 相关阅读:
    字节跳动软开校招岗
    众安保险软开校招岗
    topjui中combobox使用
    easyui中datagrid+layout布局
    jquery/js记录点击事件,单击次数加一,双击清零
    java图片上传及图片回显1
    java格式化
    java中的String整理
    删除window10没用的服务
    修改mysql默认端口
  • 原文地址:https://www.cnblogs.com/JKAI/p/7515779.html
Copyright © 2011-2022 走看看