POJ 3255 次短路问题+Dijkstra最短路优化问题
2017-06-14 20:38
337 查看
这个题真的是卡了我一天之久。。。倒并不是说它难。有一个地方一直没注意到结果一直wa。。。恶心的我都差点放弃了。。。好在最后改出来。。。这题懂得方法之后并不难。。就只是一个简单地Dijkstra求最短路问题。
题意:给出一些点和一些路径,让你找到倒数第二条最短路径。
分析:要是找到最短路径就好办了,直接无脑套用bellman-Ford或者Dijkstra就可以了,但题目让求次最短路径。想一想。次最短路径不就和最短路径一样么。无非就是再加一个数组,然后求最短路径的过程中顺便维护一个次短路径不就好了。好了,那就直接写呗。
唉,这一点就比较坑了。。。因为输入的路径没有负数,所以我一上来想到的是spfa算法。。。结果TL了。。。。。然后又换的Dijkstra,但是大佬们都说spfa可以过。。。反正用Dijstra过了。。而且这个算法还比spfa稳定。所以就不管了吧。直接上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxed=5000+10;
#define INF 0x3f3f3f3f
typedef pair<int,int> P;//这个地方我采用的是邻接表法来储存的这些点和权值
struct Node
{
int en,val;
};
int n,r,d[maxed],d2[maxed];//d数组表示最短路径数组,d2数组表示次最短路径数组
vector<Node> ve[maxed];
int main()
{
void slove(int);
scanf("%d%d",&n,&r);
int a,b,c;
for(int i=0;i<r;i++){
scanf("%d%d%d",&a,&b,&c);
Node n;
n.en=b;
n.val=c;
ve[a].push_back(n);
n.en=a;
ve[b].push_back(n);
}
slove(1);
printf("%d",d2
);
return 0;
}
void slove(int s)
{
memset(d,INF,sizeof(d));
memset(d2,INF,sizeof(d2));
d[s]=0;
priority_queue<P,vector<P>,greater<P> > pq;
pq.push(P(d[s],s));
while(!(pq.empty())){
P p=pq.top();
pq.pop();
if(d2[p.second]<p.first)
continue;
for(int i=0;i<ve[p.second].size();i++){
Node n=ve[p.second][i];
int dd=p.first+n.val;//这个地方就是让我一直wa的地方。。一开始写的dd=d[p.second]+n.val,结果一直wa。。后来终于反应过来,才意识到自己好蠢。。。这个题是要维护的次短路径!!所以这个地方并不一定要求是到某个点的最小路径。还有上边那个减小循环的地方,也是只用判断d2数组就行了。别的地方就只是一个普通的算法了。
if(d[n.en]>dd){
swap(dd,d[n.en]);
pq.push(P(d[n.en],n.en));
}
if(dd>d[n.en]&&dd<d2[n.en]){
d2[n.en]=dd;
pq.push(P(d2[n.en],n.en));
}
}
}
}
题意:给出一些点和一些路径,让你找到倒数第二条最短路径。
分析:要是找到最短路径就好办了,直接无脑套用bellman-Ford或者Dijkstra就可以了,但题目让求次最短路径。想一想。次最短路径不就和最短路径一样么。无非就是再加一个数组,然后求最短路径的过程中顺便维护一个次短路径不就好了。好了,那就直接写呗。
唉,这一点就比较坑了。。。因为输入的路径没有负数,所以我一上来想到的是spfa算法。。。结果TL了。。。。。然后又换的Dijkstra,但是大佬们都说spfa可以过。。。反正用Dijstra过了。。而且这个算法还比spfa稳定。所以就不管了吧。直接上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxed=5000+10;
#define INF 0x3f3f3f3f
typedef pair<int,int> P;//这个地方我采用的是邻接表法来储存的这些点和权值
struct Node
{
int en,val;
};
int n,r,d[maxed],d2[maxed];//d数组表示最短路径数组,d2数组表示次最短路径数组
vector<Node> ve[maxed];
int main()
{
void slove(int);
scanf("%d%d",&n,&r);
int a,b,c;
for(int i=0;i<r;i++){
scanf("%d%d%d",&a,&b,&c);
Node n;
n.en=b;
n.val=c;
ve[a].push_back(n);
n.en=a;
ve[b].push_back(n);
}
slove(1);
printf("%d",d2
);
return 0;
}
void slove(int s)
{
memset(d,INF,sizeof(d));
memset(d2,INF,sizeof(d2));
d[s]=0;
priority_queue<P,vector<P>,greater<P> > pq;
pq.push(P(d[s],s));
while(!(pq.empty())){
P p=pq.top();
pq.pop();
if(d2[p.second]<p.first)
continue;
for(int i=0;i<ve[p.second].size();i++){
Node n=ve[p.second][i];
int dd=p.first+n.val;//这个地方就是让我一直wa的地方。。一开始写的dd=d[p.second]+n.val,结果一直wa。。后来终于反应过来,才意识到自己好蠢。。。这个题是要维护的次短路径!!所以这个地方并不一定要求是到某个点的最小路径。还有上边那个减小循环的地方,也是只用判断d2数组就行了。别的地方就只是一个普通的算法了。
if(d[n.en]>dd){
swap(dd,d[n.en]);
pq.push(P(d[n.en],n.en));
}
if(dd>d[n.en]&&dd<d2[n.en]){
d2[n.en]=dd;
pq.push(P(d2[n.en],n.en));
}
}
}
}
相关文章推荐
- poj 3255 次短路问题 Dijkstra 邻接表
- POJ 2449 Remmarguts' Date【K短路问题,A*、dijkstra】
- POJ-3255-次短路问题
- POJ3255 - Roadblocks - 次短路(spfa+LLL优化)
- poj 1135 最短路(优先队列堆优化Dijkstra实现)
- POJ 1511 Invitation Cards(单源最短路,优先队列优化的Dijkstra)
- poj-3255-Roadblocks (求到源点的次短路,Dijkstra改进)
- POJ 3255 Roadblocks (次短路问题)
- poj 3255 Roadblocks Dijkstra求次短路
- POJ 3013 Big Christmas Tree【最短路变形,DIjkstra堆优化+spfa算法】
- poj 3255 次短路(第k短路) A* + spfa 或 dijkstra
- 最短路练习10/poj/1511 Invitation Cards ,(两次spfa),(单源最短路,优先队列优化的Dijkstra)
- poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)
- POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA)
- [POJ 3255]Roadblocks[dijkstra][次短路]
- POJ 3255 Roadblocks (Dijkstra求次短路)
- poj 3255 Roadblocks (次短路+dijkstra)
- POJ 3255 dijkstra次短路
- POJ 3255 Roadblocks(次短路,Dijkstra变形+邻接表存储)
- poj 1511 最短路数据加强版 dijkstra堆优化