Dijkstra + 鄰接表 + 佇列優化(最短路)
阿新 • • 發佈:2018-12-16
//https://paste.ubuntu.com/p/R2dkdC5RDh/ #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <queue> #include <vector> const int MAX = 10005 ; const int inf =0x3f3f3f3f ; using namespace std ; //Dijkstra 佇列優化 struct qnode{ int v ; // 節點編號 int c ; // 到起點的距離 qnode(int _v =0 ,int _c =0 ):v(_v),c(_c){ } ; bool operator <(const qnode &r)const { return c>r.c ; } }; struct Edge{ int v;// 邊的終點和權值 int w ; Edge(int _v=0 ,int _w =0):v(_v),w(_w){ //初始化 } }; vector <Edge> e[MAX] ; bool vis[MAX] ; int dis[MAX] ; int n ,m ; void Dijkstra(int cur) { memset(vis,false ,sizeof(vis)) ; for(int i = 1 ;i<=n ;i++) { dis[i] = inf ; } priority_queue<qnode> que ; // 按照節點到起點的距離大小作為出佇列的依據 // 距離最近的先出 // while(!que.empty()) // { // // 初始化佇列 // que.pop(); // } dis[cur] = 0 ; que.push(qnode(cur,0)); // 將源點放入,距離為0 qnode tmp ; while(!que.empty()) // 廣搜找通路 { tmp = que.top(); que.pop() ; int u = tmp.v ; // 找距離最近的編號 if(vis[u]) continue ; vis[u] = true ;// 標記訪問過了 // 下面是鬆弛操作 ; for(int i = 0 ;i<e[u].size();i++) { int v = e[u][i].v ; int w = e[u][i].w ; if(!vis[v] && dis[v] > dis[u]+w) { dis[v] = dis[u]+w ; que.push(qnode(v,dis[v])); } } } } void addedge(int u ,int v ,int w) { e[u].push_back(Edge(v,w)) ; e[v].push_back(Edge(u,w)) ; return ; } int main() { while(~scanf("%d%d",&n,&m)) { if(n==0 && m==0) { break ; } while(m--) { int u ,v ,w ; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); } Dijkstra(1); printf("%d\n",dis[n]); for(int i = 1 ;i<=n ;i++) { e[i].clear(); } } return 0 ; }
鏈式前向星存邊+佇列優化
#include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std ; const int MAX = 200005 ; const int inf = 0x3f3f3f3f ; struct Edge{ int to ; int next ; int w ; }; struct node{ int u ; int d ; bool operator < (const node &x)const { return d > x.d ; } }; Edge edge[MAX] ; int n , m , s ; int head[MAX] ; int cnt ; int dis[MAX] ; bool vis[MAX] ; inline int read() { int x=0,k=1; char c=getchar(); while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();} while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar(); return x*k; }//快讀 void Add(int u , int v ,int w ) { cnt++ ; edge[cnt].next = head[u] ; edge[cnt].to = v ; edge[cnt].w = w ; head[u] = cnt ; } inline void Dijkstra(int s) { priority_queue<node> q ; for(int i = 1 ; i<=n ;i++) { dis[i] = inf ; vis[i] = false ; } dis[s] = 0 ; q.push({s,0}); while(!q.empty()) { node tmp = q.top() ; q.pop(); int u = tmp.u ; if(vis[u]) continue ; vis[u] = true ; for(int i = head[u] ; i ; i = edge[i].next) { int v = edge[i].to ; int d = edge[i].w ; if(dis[v] > dis[u] +d) { dis[v] = dis[u]+d ; if(!vis[v]) { q.push({v,dis[v]}); } } } } } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { cnt = 0 ; if(n==0 && m==0) break ; for(int i = 0 ; i<= n ;i++) head[i] = 0 ; memset(edge,0,sizeof(edge)); for(int i = 1 ; i<=m ;i++) { int u , v ,w ; u = read() ; v = read() ; w = read() ; Add(u,v,w) ; Add(v,u,w) ; } Dijkstra(1); printf("%d\n",dis[n]); } return 0 ; }