poj 3159 Candies dijkstra + queue

题目链接:

  http://poj.org/searchproblem

题目大意:

  飞天鼠是班长,一天班主任买了一大包糖果,要飞天鼠分发给大家,班里面有n个人,但是学生A认为学生B比自己多的糖果数目不应该大于c,如果不满足自己的条件,学生A就会向老师告状,在这个班级里面泰迪熊的编号是1,班长的编号是n,班长想和泰迪熊的糖果相差最大,问:在满足m个学生的要求后,班长与泰迪熊的糖果相差最大是多少?

解题思路:

  差分约束系统,|Xa-Xb| <= c,我们假设Xa小于Xb,把糖果的最大差当成边权,因为要满足全部人的要求,也就是要求所建图的最短路,用spfa+queue优化tle了,然后我就用了dijkstra+优先队列。感觉用邻接表+优先队列对dijkstra优化真是太美妙了,省去了很多的无用枚举,但是dijkstra的先天不足还是没有办法挽救~~~~

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <queue>
 5 #include <vector>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9 #define maxn 30010
10 
11 struct Edge
12 {
13     int e, w;
14     Edge(int e=0, int w=0) : e(e),w(w) {}
15 };
16 
17 bool operator < (const Edge &a, const Edge &b)
18 {
19     return a.w > b.w;//dist小的优先级高
20 }
21 
22 vector< vector<Edge> > G;//二维vector
23 //vector<Edge>G[maxn]要比前者慢,估计申请空间需要的时间也比较可观
24 bool vis[maxn];
25 int n;
26 
27 void dijkstra();
28 
29 int main ()
30 {
31     int m;
32     while (scanf ("%d %d", &n, &m) != EOF)
33     {
34         G.clear();
35         G.resize(n+1);//动态申请空间
36         while (m --)
37         {
38             int a, b, s;
39             scanf ("%d %d %d", &a, &b, &s);
40             G[a].push_back(Edge(b, s));
41         }
42         dijkstra ();
43     }
44     return 0;
45 }
46 
47 void dijkstra()
48 {
49     priority_queue<Edge>Q;
50     Edge p, q;
51     memset (vis, false, sizeof(vis));
52     p.e = 1, p.w = 0;
53     Q.push (p);
54 
55     while (!Q.empty())
56     {
57         p = Q.top();//选取最优点
58         Q.pop();
59         if (vis[p.e])//已求出最短路,进行下一个
60             continue;
61 
62         if (p.e == n)//已求出1到n的最短路
63             break;
64         vis[p.e] = true;
65         int len = G[p.e].size();
66 
67         for (int i=0; i<len; i++)
68         {
69             q = G[p.e][i];
70             if ( !vis[q.e] )//对剩余的点进行松弛操作
71             {
72                 q.w += p.w;
73                 Q.push(q);
74             }
75         }
76     }
77     printf ("%d\n", p.w);
78 }

 

转载于:https://www.cnblogs.com/alihenaixiao/p/4241235.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值