题目大意:求次短路.
题目思路:由于可能存在重边的情况所以不能采用邻接矩阵储存图,我用了邻接表来存图。
由起点S到终点E的次短路可能由以下情况组成:
1.S到v点的次短路 + v到E的距离
2.S到v的最短路 + v到E的距离
对于每个节点,我们分别采用dist1[],dist2[]储存起点到该节点最短路与次短路
次短路的更新条件应是:对于点u,在本轮松弛操作中若 当前的dist1[u]可以被更新,我们用d2来储存还未被更新的dist1[u]。
若满足:dist2[u]>d2 && d2<dist1[u]
则更新 dist2[u]。
吐槽:实际数据范围 和题目描述的不太一样……要开大一点
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<algorithm> #include<vector> #include<queue> #define MAXSIZE 500005 #define INF 0x3f3f3f3f #define LL long long using namespace std; int ans,n,k,a[MAXSIZE],dist1[MAXSIZE],dist2[MAXSIZE],vis[MAXSIZE]; typedef pair<int, int>p;//p.second储存节点:u,p.frist储存s->u的当前最短距离 struct node { int u; int v; int w; int next; }G[MAXSIZE]; void Add(int u,int v,int w) { G[k].u=u; G[k].v=v; G[k].w=w; G[k].next=a[u]; a[u]=k++; } void dfs() { priority_queue<p,vector<p>,greater<p> > Q; dist1[1]=0; Q.push(p(0,1)); while(!Q.empty()) { p k=Q.top(); Q.pop(); int u=k.second; int d=k.first; if(dist2[u] < d) //小优化:如果取出的不是最短距离就不再向下进行 continue; for(int i=a[u];i!=-1;i=G[i].next) { int v=G[i].v; int d2=d+G[i].w; if(dist1[v] > d2) //更新最短路 { swap(dist1[v],d2); Q.push(p(dist1[v],v)); } if(dist2[v] > d2 && dist1[v]<d2)//更新次短路 { dist2[v]=d2; Q.push(p(dist2[v],v)); } } } ans=dist2[n]; } void Init() { for(int i=0;i<MAXSIZE;i++) { dist1[i]=INF; dist2[i]=INF; vis[i]=0; a[i]=-1; } k=1; } int main() { int T,cns=1,u,v,w,m; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); Init(); while(m--) { scanf("%d%d%d",&u,&v,&w); Add(u,v,w); Add(v,u,w); } dfs(); printf("Case %d: %d\n",cns++,ans); } return 0; }
时间: 2024-10-10 15:40:28