次最短路。
题意简单,无向图求次最短路。
起点,终点分别做一个SPFA。 然后 d1[u] + w[u,v] +d2[v] 就是经过此边的最短路。 只要排除掉最短,然后比较再找最短。
就是总的次短路。
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x7fffffff #define eps 1e-6 #define LL long long using namespace std; int n,m; struct lx { int v,len; }; vector <lx> g[5001]; int d1[5001],d2[5001]; void SPFA(int start,int thend,int *dis) { bool vis[5001]; for(int i=1; i<=n; i++) dis[i]=INF,vis[i]=0; queue<int>q; q.push(start); vis[start]=1,dis[start]=0; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int j=0; j<g[u].size(); j++) { int v=g[u][j].v; int len=g[u][j].len; if(dis[v]>dis[u]+len) { dis[v]=dis[u]+len; if(!vis[v]) { vis[v]=1; q.push(v); } } } } // for(int i=1; i<=n; i++) // printf("%d : %d\n",i,dis[i]); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1; i<=n; i++) g[i].clear(); int u,v,len; lx now; while(m--) { scanf("%d%d%d",&u,&v,&len); now.v=v,now.len=len; g[u].push_back(now); now.v=u; g[v].push_back(now); } int start=1,thend=n; //scanf("%d%d",&start,&thend); for(int i=1; i<=n; i++) d1[i]=d2[i]=INF; SPFA(start,thend,d1); // puts("---------"); SPFA(thend,start,d2); // puts("---------"); int ans=INF; for(int i=1; i<=n; i++) for(int j=0; j<g[i].size(); j++) { int u=i; int v=g[u][j].v; int len=g[u][j].len; int tmp=d1[u]+len+d2[v]; // printf("%d ==\n",tmp); if(tmp==d1[thend])continue; ans=min(ans,tmp); } printf("%d\n",ans); } }