Candies(差分约束系统)

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 }
View Code

 

posted @ 2013-11-22 19:30  N_ll  阅读(228)  评论(0编辑  收藏  举报