1. 程式人生 > >鏈式前向星+次短路

鏈式前向星+次短路

#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; }