【题解 P8906】 Breakdown P
Luogu P8906 Breakdown P
题意:给出一个有
输入:
3 4
10 4 4
9 5 3
2 1 6
3 1
2 3
2 1
3 2
2 2
1 3
3 3
1 1
1 2
输出:
11
18
22
22
22
-1
-1
-1
-1
这道题有人说可以暴力
由于求最短路,再加上
考虑
那么最后答案就是
那如何去求
我们可以加一个数组
那么逆向思维,从所有边都删完开始,每次加进一条边,看会对原图产生什么影响。
设此边从
首先维护好
接下来就来看
若此边为路径上的第一条边,那么就是枚举两个节点
若是第二条边或第三条边,那么只是枚举从起点到
若是第四条边,那么只是从
最后求解答案即可。
时间复杂度
Code
#include<bits/stdc++.h>
#define min(a,b) (a<b?a:b)
using namespace std;
struct datay
{
int x,y;
}l[100005];
int n,m,a[305][305],f[5][305],d[5][305],t[100005],v[3][305][305];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);
}
for(int i=1;i<=n;i++)f[1][i]=f[2][i]=f[3][i]=f[4][i]=1e9+5;
for(int i=1;i<=n;i++)d[1][i]=d[2][i]=d[3][i]=d[4][i]=1e9+5;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)v[1][i][j]=v[2][i][j]=1e9+5;
}
for(int i=1;i<=n*n+2;i++)t[i]=1e9+5;
for(int i=1;i<=n*n;i++)
{
scanf("%d%d",&l[i].x,&l[i].y);
}
int x,y;
for(int u=n*n;u>=1;u--)
{
x=l[u].x;
y=l[u].y;
t[u]=t[u+1];
v[1][x][y]=a[x][y];
for(int i=1;i<=n;i++)
{
v[2][i][y]=min(v[2][i][y],v[1][i][x]+a[x][y]);
v[2][x][i]=min(v[2][x][i],a[x][y]+v[1][y][i]);
}//维护 v 数组
for(int i=1;i<=n;i++)
{
f[1][i]=min(v[1][1][i],f[1][i]);
d[1][i]=min(v[1][i][n],d[1][i]);
f[2][i]=min(v[2][1][i],f[2][i]);
d[2][i]=min(v[2][i][n],d[2][i]);
}//维护 i=1,2 时的 f 与 d 数组
if(x==1)
{
for(int i=1;i<=n;i++)f[3][i]=min(f[3][i],a[x][y]+v[2][y][i]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
f[4][j]=min(f[4][j],a[x][y]+v[1][y][i]+v[2][i][j]);
}
}
}
if(y==n)
{
for(int i=1;i<=n;i++)d[3][i]=min(d[3][i],a[x][y]+v[2][i][x]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
d[4][j]=min(d[4][j],v[2][j][i]+v[1][i][x]+a[x][y]);
}
}
}//维护第1条边的情况
for(int i=1;i<=n;i++)
{
f[3][i]=min(f[3][i],v[1][1][x]+a[x][y]+v[1][y][i]);
d[3][i]=min(d[3][i],v[1][i][x]+a[x][y]+v[1][y][n]);
if(y==i)f[3][i]=min(f[3][i],v[2][1][x]+a[x][y]);
if(x==i)d[3][i]=min(d[3][i],a[x][y]+v[2][y][n]);
}//i=3的其他情况
for(int i=1;i<=n;i++)
{
f[4][i]=min(f[4][i],v[1][1][x]+a[x][y]+v[2][y][i]);
d[4][i]=min(d[4][i],v[2][i][x]+a[x][y]+v[1][y][n]);
f[4][i]=min(f[4][i],v[2][1][x]+a[x][y]+v[1][y][i]);
d[4][i]=min(d[4][i],v[1][i][x]+a[x][y]+v[2][y][n]);
if(y==i)f[4][i]=min(f[4][i],f[3][x]+a[x][y]);
if(x==i)d[4][i]=min(d[4][i],a[x][y]+d[3][y]);
}//i=4的其他情况
for(int i=1;i<=n;i++)t[u]=min(t[u],f[m/2][i]+d[m-m/2][i]);
}
for(int i=1;i<=n*n;i++)printf("%d\n",t[i+1]>1e9?-1:t[i+1]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧