CSP 交通規劃201609-4
阿新 • • 發佈:2019-01-27
dijkstra + 記錄陣列 + 優先佇列這裡 千萬不能加 if(cur == n) return;注意: (1) 型別1: 當題目要求到 n的最短距離時候,可以使用cur == n結束(因為此時cur == n)表示did[n]已經確定 (2) 型別2:不僅僅是隻求到n的最短距離,此時cur == n如果返回了,其它的臨接點最短距離可能並未確定, cur == n只是表示到n的最短距離確定了,此題就是要求到所有點都是最短距離前提下取,到某個點路徑相同時候最小的前驅,因而不能cur == n直接就返回了。
#include<stdio.h> #include<algorithm> #include<cmath> #include<string.h> #include<queue> #include<vector> using namespace std; #define INF 0x3f3f3f3f #define MAXN 10005 #define MAXM 100005 typedef long long ll; struct Edge{ int to, w; Edge(){} Edge(int pto, int pw){ to = pto; w = pw; } bool operator < (const Edge o)const{ return w > o.w; } }; int n,m; ll dis[MAXN]; bool vis[MAXN]; int pre[MAXN];//記錄某點直接到達該點的最小長度 vector<Edge> adj[MAXN]; priority_queue<Edge> pq; void dijkstra(int s) { memset(vis,false,sizeof(vis)); memset(dis,INF,sizeof(dis)); memset(pre,INF,sizeof(pre)); dis[s] = 0; pre[s] = 0; pq.push(Edge(s,dis[s])); while(!pq.empty()){ Edge tmp = pq.top(); pq.pop(); int cur = tmp.to; // if(cur == n){ //不能有這個 // return ; // } if(vis[cur]) continue; vis[cur] = true; for(int i = 0; i < adj[cur].size(); ++i){ Edge e = adj[cur][i]; if(!vis[e.to]){ if(dis[e.to] > dis[cur] + e.w){ dis[e.to] = dis[cur] + e.w; pre[e.to] = e.w; pq.push(Edge(e.to,dis[e.to])); } else if(dis[e.to] == dis[cur] + e.w){//到某個點最短距離相同時候,取最小的前驅 pre[e.to] = min(e.w,pre[e.to]); } } } } } int main() { scanf("%d%d",&n,&m); int f,t,w; for(int i = 0; i < m; ++i){ scanf("%d%d%d",&f,&t,&w); adj[f].push_back(Edge(t,w)); adj[t].push_back(Edge(f,w)); } dijkstra(1); ll ans = 0; for(int i = 2; i <= n; ++i){ ans += pre[i]; } printf("%d",ans); return 0; }