题意:给出一个无向图,然后求1到n点的次短路
分析:两种做法,第一种,Astat+最短路求k短路的方法。
第二种是比较暴力的方法。
先求1点到所有点的最短路dis1
然后求n点到所有点的最短路dis2
然后枚举所有边,则次短路为dis1【from】 + dis2【to】 + w【i】中大于最短路的最短的。
AC代码:
#include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; const int N = 5700; const int inf = 0x3f3f3f3f; struct Node { int to,val; }; vector<Node> g[N],rg[N]; int dis[N]; bool vis[N]; int n,m; void SPFA(int src) { int i; memset(dis,inf,sizeof(dis)); dis[src] = 0; queue<int> Q; Q.push(src); while(!Q.empty()) { int u,v; u = Q.front(); Q.pop(); for(int i = 0;i<g[u].size();i++) { v = g[u][i].to; if(dis[v]>dis[u]+g[u][i].val) //记得这里这样写 最后改一下vis { dis[v] = dis[u] + g[u][i].val; Q.push(v); } } } } int dis1[N]; void SPFA1(int src) { int i; memset(dis1,inf,sizeof(dis1)); dis1[src] = 0; queue<int> Q; Q.push(src); while(!Q.empty()) { int u,v; u = Q.front(); Q.pop(); for(int i = 0;i<g[u].size();i++) { v = g[u][i].to; if(dis1[v]>dis1[u]+g[u][i].val) //记得这里这样写 最后改一下vis { dis1[v] = dis1[u] + g[u][i].val; Q.push(v); } } } } void Clear(int x) { for(int i=0;i<=x;i++){ g[i].clear(); rg[i].clear(); } } int x[101000],y[101000],z[101000]; int main() { //freopen("a.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { for(int i=0;i<m;i++) { scanf("%d%d%d",&x[i],&y[i],&z[i]); g[y[i]].push_back((Node){x[i],z[i]}); g[x[i]].push_back((Node){y[i],z[i]}); rg[x[i]].push_back((Node){y[i],z[i]}); rg[y[i]].push_back((Node){x[i],z[i]}); } int s=1,t=n,k=2; SPFA(t); SPFA1(s); int mi = dis1[t]; int ans = inf; for(int i=0;i<m;i++) { int tmp = dis[y[i]] + dis1[x[i]] + z[i]; int css = dis[x[i]] + dis1[y[i]] + z[i]; if(tmp>mi) ans = min(ans,tmp); if(css>mi) ans = min(ans,css); } printf("%d\n",ans); Clear(n); } return 0; }
时间: 2024-10-21 21:26:56