鏈式前向星+次短路
阿新 • • 發佈:2018-12-30
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int R = 100000+5; const int INF = 0x3f3f3f3f; struct Node { int v; int w; int next;//儲存前一個點在陣列的位置 } edge[R*2]; int head[R];//儲存最後一個點每個點在的陣列位置 int dist1[R],dist2[R];//距離陣列,分別求1到所有點距離和n到所有點距離bool vis[R]; int num; int n,m; void init() { num = 0; memset(head,-1,sizeof(head)); memset(dist1,0x3f,sizeof(dist1)); memset(dist2,0x3f,sizeof(dist2)); } void add_edge(int u,int v,int w)//鄰接表 { edge[num].v = v; edge[num].w = w; edge[num].next = head[u]; head[u] = num++; }void SPFA(int u,int *dist)//u是給定點 dist是距離陣列 { int i,v,w; queue<int> Q; memset(vis,false,sizeof(vis)); dist[u] = 0; vis[u] = true; Q.push(u); while(!Q.empty()) { u = Q.front(); Q.pop(); vis[u] = false; for(i=head[u]; i!=-1; i=edge[i].next) { v= edge[i].v; w = edge[i].w; if(dist[v] > dist[u] + w) { dist[v] = dist[u] + w; if(!vis[v]) { vis[v] = true; Q.push(v); } } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF)//n個點,m條邊 { int u,v,w;; init(); for(int i=1; i<=m; i++) //無向圖,雙向間圖 { scanf("%d%d%d",&u,&v,&w); add_edge(u,v,w); add_edge(v,u,w); } SPFA(1,dist1);//求 1 到所有點的最短路 SPFA(n,dist2);//求 n 到所有點的最短路 int ans = INF; for(int i=1; i<=n; i++)//遍歷每個點 { for(j=head[i]; j!=-1; j=edge[j].next)//與i點相連的邊 { v = edge[j].v; w = edge[j].w; // 1 到 i這一點的最短路, n 到 j這一點的最短路 + edge[i][j] int tem = dist1[i] + dist2[v] + w; if(tem > dist1[n] && tem < ans) { ans = tem; } } } printf("%d\n",ans); } return 0; }