牛客多校第四场 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[1003][1003]; int dis[1003][1003];//删去了i条边后第j个点最短距离 priority_queue<Point,vector<Point>,greater<Point> > que[1003]; vector<Point>link[1003]; 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=1;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=1;i<n;i++){ for(int j=i+1;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[0].push(Point(s,0)); dis[0][s]=0; for(int i=0;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=0;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+1][v]>nowd){ dis[i+1][v]=nowd; que[i+1].push(Point(v,dis[i+1][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=0;i<=k;i++){ minn=min(minn,dis[i][t]); } printf("%d\n",minn); }