1 条题解

  • 0
    @ 2026-7-2 14:50:36

    非常模板的最短路题。

    题意

    NN 个点 MM 条边的无向图,第 ii 条边连接 AiA_iBiB_i,长度为 CiC_i

    你需要依次执行 QQ 次操作:

    • 1 i:断开第 ii 条边。
    • 2 x y 查询 xxyy 的最短路径长度,如果无法到达输出 1-1

    保证无重边自环,第 11 种操作不超过 300300 次。

    分析

    断开边不好做,可以离线下来逆序处理操作,这样就从断边变成了加边。

    查询的是全源最短路,先使用 Floyd 求出任意两点间的最短路径长度。

    在加边 (u,v)(u,v) 的时候,枚举两个点 i,ji,j,最短路径有 33 种情况:

    • i,ji,j 的最短路径不经过这条边。
    • ii 走到 uu,经过 (u,v)(u,v) 边后再从 vv 走到 jj
    • ii 走到 vv,经过 (v,u)(v,u) 边后再从 uu 走到 jj

    因为第一种操作的数量不超过 300300 次,所以可以直接枚举两个端点取以上三种情况的最小值。

    Q1Q_1 为第 11 种操作次数,时间复杂度 O(n3+Q1n2)O(n^3 + Q_1n^2)

    代码

    //the code is from chenjh
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    int n,m,q;
    struct Edge{
    	int u,v,w;
    }e[300*300];
    bool ct[300*300];//标记哪些边被砍掉了。
    LL d[305][305];
    struct QUE{
    	int op,x,y;
    }Q[200005];
    LL ans[200005];
    void add(const int u,const int v,const LL&w){d[u][v]=min(d[u][v],w);}
    int main(){
    	scanf("%d%d%d",&n,&m,&q);
    	for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    	for(int i=1;i<=q;i++){
    		scanf("%d%d",&Q[i].op,&Q[i].x);
    		if(Q[i].op==2) scanf("%d",&Q[i].y);
    		else ct[Q[i].x]=1;//标记该边被断开。
    	}
    	memset(d,0x3f,sizeof d);//赋值无穷大。
    	for(int i=1;i<=n;i++) d[i][i]=0;
    	for(int i=1;i<=m;i++)if(!ct[i])
    		add(e[i].u,e[i].v,e[i].w),add(e[i].v,e[i].u,e[i].w);/添加未被断开的边。
    	for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]);//Floyd 求最短路,注意转移顺序 k,i,j。
    	for(int _=q,i;_>0;--_){//从后往前逆序处理操作。
    		if(Q[_].op==1){
    			i=Q[_].x,add(e[i].u,e[i].v,e[i].w),add(e[i].v,e[i].u,e[i].w);
    			for(int u=1;u<=n;u++)for(int v=1;v<=n;v++) d[u][v]=min({d[u][v],d[u][e[i].u]+e[i].w+d[e[i].v][v],d[u][e[i].v]+e[i].w+d[e[i].u][v]});//枚举端点,获得三种情况的最小值。
    		}
    		else ans[_]=d[Q[_].x][Q[_].y];//获得查询答案。
    	}
    	for(int _=1;_<=q;_++)if(Q[_].op==2) printf("%lld\n",ans[_]>=0x3f3f3f3f3f3f3f3fll?-1:ans[_]);//如果距离为无穷大即无法到达,输出 -1。
    	return 0;
    }
    
    • 1

    信息

    ID
    7927
    时间
    2500ms
    内存
    1024MiB
    难度
    8
    标签
    递交数
    23
    已通过
    5
    上传者