题解 [ABC375F] Road Blocked

【洛谷专栏】

非常模板的最短路题。

题意

N 个点 M 条边的无向图,第 i 条边连接 AiBi,长度为 Ci

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

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

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

分析

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

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

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

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

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

Q1 为第 1 种操作次数,时间复杂度 O(n3+Q1n2)

代码

//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;
}
posted @   Chen_Jinhui  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)

一言

你将不再是道具,而是成为人如其名的人。
——紫罗兰的永恒花园
点击右上角即可分享
微信分享提示