http://poj.org/problem?id=3159
思路:用O(V+ElogV)的Dijkstra算法求1到n的最短路。即用优先队列优化Dijkstra算法。
1 #include <stdio.h> 2 #include <queue> 3 #include <string.h> 4 using namespace std; 5 const int maxn=300005; 6 const int maxm=150002; 7 struct node 8 { 9 int u,v,w; 10 int next; 11 } edge[maxm]; 12 struct pot 13 { 14 int v,w; 15 pot(int v = 0,int w = 0):v(v),w(w) {} 16 bool operator < (const pot &a)const 17 { 18 return w > a.w; 19 } 20 }; 21 int n,m; 22 int head[maxn],vis[maxn],dis[maxn],cnt; 23 void add(int u,int v,int w) 24 { 25 edge[cnt].u = u; 26 edge[cnt].v = v; 27 edge[cnt].w = w; 28 edge[cnt].next = head[u]; 29 head[u] = cnt++; 30 } 31 void Dijkstra(int s) 32 { 33 memset(vis,0,sizeof(vis)); 34 memset(dis,65,sizeof(dis)); 35 dis[s] = 0; 36 priority_queue<pot>q; 37 q.push(pot(s,dis[s])); 38 for(int i = 0; i < n; i++) 39 { 40 while(!q.empty()&&vis[q.top().v])//去掉队首被标记的点 41 q.pop(); 42 if (q.empty()) break; 43 pot pre = q.top();//取出队首的点,即权值最小的点 44 q.pop(); 45 vis[pre.v] = 1;//标记 46 for (int j = head[pre.v]; j !=-1; j= edge[j].next)//找出pre的所有连接点 47 { 48 int v = edge[j].v; 49 if (!vis[v] && dis[pre.v]+edge[j].w < dis[v])//更新所有点到源点的距离 50 { 51 dis[v] = dis[pre.v]+edge[j].w; 52 q.push(pot(v,dis[v]));//将更新后的点与权值入队列 53 } 54 } 55 56 } 57 58 } 59 int main() 60 { 61 int u,v,w; 62 cnt = 0; 63 scanf("%d %d",&n,&m); 64 memset(head,-1,sizeof(head)); 65 for (int i = 0; i < m; i++) 66 { 67 scanf("%d %d %d",&u,&v,&w); 68 add(u,v,w); 69 } 70 Dijkstra(1); 71 printf("%d\n",dis[n]); 72 return 0; 73 }