poj3159 Candies(差分约束,dij+heap)

poj3159 Candies

这题实质为裸的差分约束。

先看最短路模型:若d[v] >= d[u] + w, 则连边u->v,之后就变成了d[v] <= d[u] + w , 即d[v] – d[u] <= w。

再看题目给出的关系:b比a多的糖果数目不超过c个,即d[b] – d[a] <= c ,正好与上面模型一样,

所以连边a->b,最后用dij+heap求最短路就行啦。

ps:我用vector一直TLE,后来改用链式前向星才过了orz。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<vector>
 6 #include<set>
 7 #define CLR(a,b) memset((a),(b),sizeof((a)))
 8 using namespace std;
 9 
10 const int N = 30001;
11 const int M = 150001;
12 const int inf = 0x3f3f3f3f;
13 
14 int n, m;
15 bool s[N];
16 int head[N];
17 int cnt;
18 struct edge{
19     int nex;
20     int v, w;
21 }g[M];
22 struct node{
23     int v, w;
24     node(int _v=0,int _w=0):v(_v),w(_w){}
25     bool operator < (const node&r)const{
26         return r.w < w;
27     }
28 };
29 void add_edge(int u,int v,int w){
30     g[cnt].v = v;
31     g[cnt].w = w;
32     g[cnt].nex = head[u];
33     head[u] = cnt++;
34 }
35 void dij(){
36     int i, u, v, w;
37     node t;
38     CLR(s, 0);
39     priority_queue<node>q;
40     q.push(node(1,0));
41     while(!q.empty()){
42         t = q.top(); q.pop();
43         u = t.v;
44         if(s[u]) continue;
45         s[u] = 1;
46         if(u == n) break;
47         for(i = head[u]; ~i; i = g[i].nex){
48             v = g[i].v;
49             if(!s[v]){
50                 w = t.w + g[i].w;
51                 q.push(node(v, w));
52             }
53         }
54     }
55     printf("%d
", t.w);
56 }
57 int main(){
58     int i, j, a, b, c;
59     scanf("%d %d", &n, &m);
60     cnt = 0;
61     CLR(head, -1);
62     for(i = 1; i <= m; ++i){
63         scanf("%d %d %d", &a, &b, &c);
64         add_edge(a,b,c);
65     }
66     dij();
67     return 0;
68 }
View Code
原文地址:https://www.cnblogs.com/GraceSkyer/p/5873520.html