一道删边最短路的题目

给一个无向图和s、t,每次删掉一条边,询问每次删除后s到t的最短路是否改变。询问互相独立。

从s、t分别跑最短路建出最短路网,然后在最短路网上找割边。

询问的边如果在最短路网上且是割边就改变了,否则不变。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define SZ 456789
int n;
namespace spfa
{
int M=0,vb[SZ],dst[SZ],fst[SZ],nxt[SZ],q[SZ],d1[SZ],d2[SZ],vc[SZ],ids[SZ],f1[SZ],f2[SZ];
bool iq[SZ];
void ad_dl(int a,int b,int c,int id)
{
    ++M; nxt[M]=fst[a]; fst[a]=M; vb[M]=b; vc[M]=c; ids[M]=id;
}
void getsp(int* d,int* f,int S)
{
    int h=0,t=1; q[0]=S;
    for(int i=1;i<=n;i++) d[i]=1000000000, iq[i]=0;
    d[S]=0; iq[S]=1;
    while(h!=t)
    {
        int cur=q[h++]; h&=524287;
        for(int e=fst[cur];e;e=nxt[e])
        {
            int b=vb[e],c=vc[e];
            if(d[b]<=d[cur]+c) continue;
            d[b]=d[cur]+c; f[b]=cur;
            if(!iq[b]) q[t++]=b;
            t&=524287;
        }
        iq[cur]=0;
    }
}
}
namespace cute
{
int M=0,vb[SZ],fst[SZ],nxt[SZ];
void ad_dl(int a,int b)
{
    ++M; nxt[M]=fst[a]; fst[a]=M; vb[M]=b;
}
void addl(int a,int b) {ad_dl(a,b); ad_dl(b,a);}
int dfn[SZ],low[SZ],C=0;
void tarjan(int x,int f)
{
    dfn[x]=low[x]=++C;
    for(int e=fst[x];e;e=nxt[e])
    {
        int b=vb[e];
        if(!dfn[b])
        {
            tarjan(b,x);
            low[x]=min(low[b],low[x]);
        }
        else if(b!=f) low[x]=min(low[x],dfn[b]);
    }
}
}
int xs[SZ],ys[SZ],zs[SZ];
bool out[SZ];
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);} 
int main()
{
    FO(school)
    using namespace spfa;
    int s,t,m;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        xs[i]=x; ys[i]=y; zs[i]=z;
        spfa::ad_dl(x,y,z,i);
        spfa::ad_dl(y,x,z,i);
    }
    getsp(d1,f1,s); getsp(d2,f2,t);
    for(int i=1;i<=n;i++) dst[i]=d1[i]+d2[i];
    int tar=dst[t];
    for(int i=1;i<=m;i++)
    {
        bool ok=1;
        if(d1[xs[i]]+d2[ys[i]]+zs[i]==tar) cute::addl(xs[i],ys[i]);
        else if(d2[xs[i]]+d1[ys[i]]+zs[i]==tar) cute::addl(xs[i],ys[i]);
        else ok=0;
        if(!ok) out[i]=1;
    }
    for(int i=1;i<=n;i++) if(!cute::dfn[i]) cute::tarjan(i,0);
    using namespace cute;
    int q; scanf("%d",&q);
    while(q--)
    {
        int e;
        scanf("%d",&e);
        int x=xs[e],y=ys[e];
        if(!out[e]&&(low[x]>dfn[y]||low[y]>dfn[x])) puts("No");
        else puts("Yes");
    }
}
原文地址:https://www.cnblogs.com/zzqsblog/p/5575709.html