牛客多校第四场 J Free 最短路

时间:2023-03-09 20:14:51
牛客多校第四场 J Free 最短路

题意:

求最短路,但是你有k次机会可以把路径中某条边的长度变为0.

题解:

跑k+1次迪杰斯特拉,设想有k+1组dis数组和优先队列,第k组就意味着删去k条边的情况,每次松弛操作,松弛的两点i,j和距离l(i,j),不仅更新本组的dis数组令dis[j]=dis[i]+l[i,j],还更新下一组,令dis`[j]=dis[i],相当于删去边(i,j)

#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#define INF 0x3f3f3f3f
struct Point{
int n,dis;
friend bool operator >(const Point &a,const Point &b){
return a.dis>b.dis;
}
friend bool operator <(const Point &a,const Point &b){
return a.dis<b.dis;
}
Point(){}
Point(int a,int b){
n=a;dis=b;
}
};
using namespace std;
int lik[][];
int dis[][];//删去了i条边后第j个点最短距离
priority_queue<Point,vector<Point>,greater<Point> > que[];
vector<Point>link[];
int main(){
int n,m,s,t,k;
scanf("%d %d %d %d %d",&n,&m,&s,&t,&k); memset(dis,INF,sizeof dis);
memset(lik,INF,sizeof lik);
for(int i=;i<=m;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if(a==b)continue;
else{
lik[a][b]=min(lik[a][b],c);
lik[b][a]=min(lik[b][a],c);
}
} // for(int i=1;i<=n;i++){
// for(int j=1;j<=n;j++){
// printf("%d ",lik[i][j]);
// }
// printf("\n");
// } for(int i=;i<n;i++){
for(int j=i+;j<=n;j++){
if(lik[i][j]<INF){
link[i].push_back(Point(j,lik[i][j]));
link[j].push_back(Point(i,lik[j][i]));
} }
} // for(int i=1;i<=n;i++)printf("%d ",link[i].size()); // system("pause");
que[].push(Point(s,));
dis[][s]=; for(int i=;i<=k;i++){
while(!que[i].empty()){ Point tmp=que[i].top();
que[i].pop();
int u=tmp.n;
int nowd=tmp.dis;
if(nowd>dis[i][u])continue; // printf("*%d %d\n",u,nowd); for(int j=;j<link[u].size();j++){
int v=link[u][j].n;
int d=link[u][j].dis; if(dis[i][v]>nowd+d){
dis[i][v]=nowd+d;
que[i].push(Point(v,dis[i][v]));
} if(i<k && dis[i+][v]>nowd){
dis[i+][v]=nowd;
que[i+].push(Point(v,dis[i+][v]));
} // for(int w=0;w<=k;w++){
// for(int r=1;r<=n;r++){
// printf("%d ",dis[w][r]);
// }
// printf("\n");
// }
// printf("\n"); } }
}
// for(int w=0;w<=k;w++){
// for(int r=1;r<=n;r++){
// printf("%d ",dis[w][r]);
// }
// printf("\n");
// }
int minn=INF;
for(int i=;i<=k;i++){
minn=min(minn,dis[i][t]);
}
printf("%d\n",minn);
}