题解 [ABC375F] Road Blocked
非常模板的最短路题。
题意
你需要依次执行
1 i
:断开第 条边。2 x y
查询 到 的最短路径长度,如果无法到达输出 。
保证无重边自环,第
分析
断开边不好做,可以离线下来逆序处理操作,这样就从断边变成了加边。
查询的是全源最短路,先使用 Floyd 求出任意两点间的最短路径长度。
在加边
的最短路径不经过这条边。- 从
走到 ,经过 边后再从 走到 。 - 从
走到 ,经过 边后再从 走到 。
因为第一种操作的数量不超过
设
代码
//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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)