洛谷P2865 次短路
本题是个次短路板子题,因为我太弱了所以我不会K短路。
考虑从1点跑一边最短路,然后从N点再跑个最短路。之后遍历这个图,然后更新答案。
Code:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define ll long long #define INF 0x3f3f3f3f #define maxn 100001 using namespace std; struct Edge{ int nxt,to,dis; }edge[maxn*2]; int head[maxn],num_edge,dis[maxn],vis[maxn],n,r,Dis[maxn]; inline void addedge(int from,int to,int dis){ edge[++num_edge].nxt=head[from]; edge[num_edge].to=to; edge[num_edge].dis=dis; head[from]=num_edge; } inline void spfa(int s){ memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); queue<int> q; q.push(s); vis[s]=1; dis[s]=0; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i;i=edge[i].nxt){ int y=edge[i].to; if(dis[y]>dis[x]+edge[i].dis){ dis[y]=dis[x]+edge[i].dis; if(vis[y]==0){ vis[y]=1; q.push(y); } } } } } inline void spfa_(int s){ memset(vis,0,sizeof(vis)); memset(Dis,INF,sizeof(Dis)); queue<int> q; q.push(s); vis[s]=1; Dis[s]=0; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i;i=edge[i].nxt){ int y=edge[i].to; if(Dis[y]>Dis[x]+edge[i].dis){ Dis[y]=Dis[x]+edge[i].dis; if(vis[y]==0){ vis[y]=1; q.push(y); } } } } } int main(){ cin>>n>>r; for(int i=1;i<=r;i++){ int u,v,w; cin>>u>>v>>w; addedge(u,v,w); addedge(v,u,w); } spfa(1); spfa_(n); int minn=dis[n]; int ans=INF; for(int i=1;i<=n;i++){ for(int j=head[i];j;j=edge[j].nxt){ int v=edge[j].to,w=edge[j].dis; if(dis[i]+Dis[v]+w>minn&&dis[i]+Dis[v]+w<ans){ ans=dis[i]+Dis[v]+w; } } } cout<<ans; return 0; }