POJ3159---Candies(最短路:spfa+栈or队列)(邻接表)
来源:互联网 发布:仓鼠用品淘宝 编辑:程序博客网 时间:2024/06/17 13:52
【题意来源】:http://poj.org/problem?id=3159
【题意】
班长分糖,规定是,B童鞋分的糖不能超过A童鞋C个(输入数据:A B C),那么,假设共有n个同学,编号1~n,那么n好同学最多比1号同学多多少个?
【思路】
不等式问题,可由差分约束系统转变为最短路问题。(差分约束现在还不大懂。。)
大致说一下我的思考过程:
假设S数组代表最优情况下每个人得到的糖的数量,那么由题意可得:
S(B)-S(A)<=C,转化为:S(B)<=S(A)+C。
那么,就可以转变为最短路问题,也即是:
if(S(B)>S(A)+C) S(B)=S(A)+C。求出最短路。
但是有的人会疑问:不是让求max(S(n)-S(1)),这样下去只会得到min(S(n)-S(1))。这个问题我也不大懂。先给出链接:浅析差分约束系统,但是按照我上面推导是大于还是小于是没有错的。。。
还有一点要说明:这道题非常卡数据、卡时间。
数据问题呢,我用双向队列试了出来,最短路的spfa算法呢,每从队列里拿出一个点(被更新过的,要么就是起点),用于更新其他点,那么假设当前取出一个点去更新完一个点后,被更新的点将何去何从?
分析:
优先队列:会被丢进队列,然后自动排序,队首依旧是最小的那个。
普通队列:会被丢进队尾,需要前面的被取出完才能被取出。
栈:会被丢进队首,当前点更新所有点之后,会被取出。
这道题,绝大部分用栈(又名堆栈)过的这道题,那么栈和队列有什么区别呢?
相同的时间复杂度下,队列是队尾进,队首出,而栈是队首进,队首出。
而优先队列就是优化了一部分多余的查找过程,队首就直接是最小的(但是可能由于卡时间,所以普通的优先队列过不了),那么,为什么队列会TLE,而栈没有呢。。。我想到的唯一原因是。。数据问题,更新的点刚好是最小的点,然后放在队首。。。
【代码1】
516ms
#include<cmath>#include<cstdio>#include<queue>#include<vector>#include<cstring>#include<algorithm>#define INF 0x3f3f3f3fusing namespace std;int n,m,tot;struct pp{ int v,w; int nexx;}edge[150000+10];int vis[30000+10],d[30000+10],first[30000+10];int spot[30000+10];void spfa(){ memset(vis,0,sizeof(vis)); for(int i=2;i<=n;i++) d[i]=INF; d[1]=0; int top=1; spot[1]=1; vis[1]=1; while(top!=0) { int res=spot[top--]; vis[res]=0; for(int i=first[res];i!=-1;i=edge[i].nexx) { if(d[edge[i].v]>d[res]+edge[i].w) { d[edge[i].v]=d[res]+edge[i].w; if(!vis[edge[i].v]) { spot[++top]=edge[i].v; vis[edge[i].v]=1; } } } } printf("%d\n",d[n]);}int main(){ scanf("%d%d",&n,&m); tot=0; for(int i=1;i<=n;i++) first[i]=-1; while(m--) { int u,v,w; scanf("%d%d%d",&u,&v,&w); edge[tot].nexx=first[u]; edge[tot].v=v; edge[tot].w=w; first[u]=tot++; } spfa();}
【代码2】
deque(双向队列)实现的栈的功能(实现的队列依旧会TLE)657ms
#include<cmath>#include<cstdio>#include<queue>#include<vector>#include<cstring>#include<algorithm>#define INF 0x3f3f3f3fusing namespace std;int n,m,tot;struct pp{ int v,w; int nexx;}edge[150000+10];int vis[30000+10],d[30000+10],first[30000+10];int spot[30000+10];void spfa(){ memset(vis,0,sizeof(vis)); for(int i=2;i<=n;i++) d[i]=INF; d[1]=0; deque<int> q; vis[1]=1; q.push_back(1); while(!q.empty()) { int res=q.front(); q.pop_front(); vis[res]=0; for(int i=first[res];i!=-1;i=edge[i].nexx) { if(d[edge[i].v]>d[res]+edge[i].w) { d[edge[i].v]=d[res]+edge[i].w; if(!vis[edge[i].v]) {// if(!q.empty()&&d[edge[i].v]<d[q.front()]) q.push_front(edge[i].v);// else// q.push_back(edge[i].v); vis[edge[i].v]=1; } } } } printf("%d\n",d[n]);}int main(){ scanf("%d%d",&n,&m); tot=0; for(int i=1;i<=n;i++) first[i]=-1; while(m--) { int u,v,w; scanf("%d%d%d",&u,&v,&w); edge[tot].nexx=first[u]; edge[tot].v=v; edge[tot].w=w; first[u]=tot++; } spfa();}
- POJ3159---Candies(最短路:spfa+栈or队列)(邻接表)
- spfa+队列+邻接表POJ3159
- POJ3159-Candies-最短路
- poj3159 Candies(差分约束,最短路)
- poj3159 Candies(查分约束最短路)
- POJ3159 Candies(差分约束+SPFA的栈实现)
- spfa+栈+邻接表模板POJ3159
- POJ3159 Candies(最短路径:SPFA+链表+栈)
- poj3159(spfa+栈)
- 旧代码 - 最短路 Spfa(邻接表)
- POJ 1511(邻接表和最短路 SPFA)
- 最短路SPFA算法 (通过邻接表来实现)
- spfa求最短路模板(邻接表)
- poj3159 Candies 最短路&差分约束
- poj3159——Candies(差分约束+SPFA堆栈)
- POJ 3159 Candies(spfa最短路,差分约束)
- poj3159-Candies差分约束-spfa+栈
- poj3159 Candies(SPFA+stack)
- Java关键字——final详谈
- kmp(基本操作)
- php echo 和 print的区别
- 教教你如何下载去掉水印的美拍视频
- session的使用方法及实例
- POJ3159---Candies(最短路:spfa+栈or队列)(邻接表)
- 06 在mysql使用full join
- Java 观察者模式
- Log4j的使用
- Lucky Permutation Triple CodeForces
- Memcache总结
- Apache 301重定向
- POJ 2546 Circular Area 笔记
- MAC 上windows的caps lock 按下变成大写不能切换问题