bzoj1726 [Usaco2006 Nov]Roadblocks第二短路

来源:互联网 发布:ubuntu des 解密 编辑:程序博客网 时间:2024/05/18 15:56

次短路的裸题,由于不是树不能用dp,所以spfa分情况讨论就好了
disa[x]+val[i]小于disa[v]时,将原来的disa[v]更新disb,然后disa[x]更新disa[v]
disa[x]+val[i]大于disa[v]时,如果disb[v]小于disb[x]+val[i]就可以用disa[x]+val[i]更新disb[v]
最后就是disa[v]==disa[x]+val[i]时,直接用disb[x]更新disb[v]就可以了。

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)#define inf 0x3c3c3c3cusing namespace std;const int N=3e5+5;int head[N],go[N],next[N],val[N];int q[N],disa[N],disb[N];bool vis[N];int n,m,tot;inline void spfa(){    memset(vis,0,sizeof(vis));    fo(i,1,n)disa[i]=disb[i]=inf;    int t=0,w=1;    disa[1]=0;    vis[1]=1;    q[1]=1;    while (t!=w)    {        ++t;        if (t==100001)t=0;        int x=q[t];        for(int i=head[x];i;i=next[i])        {            int v=go[i];            bool flag=0;            if (disa[x]+val[i]<disa[v])            {                disb[v]=min(disa[v],disb[x]+val[i]);                disa[v]=disa[x]+val[i];                flag=1;            }            else if (disa[x]+val[i]>disa[v]&&disa[x]+val[i]<disb[v])            {                disb[v]=disa[x]+val[i];                flag=1;            }            else if (disa[x]+val[i]==disa[v]&&disb[x]+val[i]<disb[v])            {                disb[v]=disb[x]+val[i];                flag=1;            }            if (flag&&!vis[v])            {                vis[v]=1;                ++w;                if (w==100001)w=0;                q[w]=v;            }        }        vis[x]=0;    }}inline void add(int x,int y,int z){    go[++tot]=y;    next[tot]=head[x];    val[tot]=z;    head[x]=tot;}int main(){    scanf("%d%d",&n,&m);    fo(i,1,m)    {        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        add(x,y,z);        add(y,x,z);    }    spfa();    printf("%d\n",disb[n]);    return 0;}
阅读全文
0 0