Dijkstra算法之五----邻接链表+优先队列实现Dijkstra算法

//邻接链表+优先队列 实现Dijstra 算法

//poj 3159 Candies

//在满足b1-a1<=c1,b2-a1<=c2...的情况下,flymouse( N )希望自己分得的糖果数尽量多于snoopy( 1 )
//b-a<=c不等式正好可以构成最短路的三角不等式:dv <= du + w(u,v)
//比如顶点A,B,C有如下关系:db-da<=2,dc-da<=5,dc-db<=2,构成一三角形ABC,
//AB(A指向B),AC(A指向C),BC(B指向C),由dc-db<=2,db-da<=2,知dc<=db+2,db<=da+2,所以dc<=da+4
//而原条件 dc-da<=5,即dc<=da+5, 二者相比较,结果是dc<=da+4 所以实际上是求最短路
//要使得|dn-d1|的值最大,我们只关心二者的相对量,而不关心其绝对量,所以完全可以假定d1=0
//以V1作为起点,distD[1]=0;求最短路径,distD[N]就是所求的


#include
<iostream> //邻接链表+优先队列, 时间1469MS
#include<queue>
using namespace std;
#define inf 0x7fffffff
int Vertex,distD[30002],i,j;
typedef pair
<int,int> ele;
struct Edge
{
int index;
int weight;
Edge
*next;
}table[
30002];

void graph()
{
int e, a,b,c;
scanf(
"%d%d",&Vertex,&e);
for(i=1;i<=Vertex;++i)
table[i].next
=NULL;
while(e--)
{
scanf(
"%d%d%d",&a,&b,&c);
Edge
*q=new Edge; //耗时间
q->index=b;q->weight=c;
q
->next=table[a].next; table[a].next=q; //始终都是在前面插入结点
}
}
void Dijstra(int v)
{
fill(distD,distD
+Vertex+1,inf);
distD[v]
=0;
priority_queue
<ele,vector<ele>,greater<ele> > col;
col.push(make_pair(distD[v],v));
while(!col.empty())
{
ele u
=col.top();col.pop();
int x=u.second;
if(distD[x]!=u.first)
continue;

Edge
* curr=table[x].next;
while(curr!=NULL)
{
int vv=curr->index,w=curr->weight;
if(distD[x]+w<distD[vv])
{
distD[vv]
=distD[x]+w;
col.push(make_pair(distD[vv],vv));
}
curr
=curr->next;
}
}
}
int main()
{
graph();
Dijstra(
1);
printf(
"%d\n",distD[Vertex]);
return 0;
}

  

//poj 3159 Candies的类似实现代码:

#include
<iostream> //579MS!!
#include<cstring>
#include
<cstdio>
#include
<queue>
using namespace std;
#define INF 999999999
struct node
{
int y,v,next;
}a[
150010];
int cnt,head[30010],n,m;
void ad(int x,int y,int v)
{
a[cnt].next
=head[x];
a[cnt].y
=y;
a[cnt].v
=v;
head[x]
=cnt++;
}
struct Dis
{
int y,dis;
bool operator<(const Dis &a) const
{
return dis>a.dis;}
};
int dijkstra()
{
Dis c,tmp;
c.y
=1;c.dis=0;
int dis[30010];
for(int i=1;i<=n;i++)
dis[i]
=INF;
dis[
1]=0;
priority_queue
<Dis> q;
q.push(c);
while(!q.empty())
{
c
=q.top();q.pop();
int x=c.y;
if(dis[x]<c.dis)continue;
for(int i=head[x];i!=-1;i=a[i].next)
if(dis[a[i].y]>dis[x]+a[i].v)
{
dis[a[i].y]
=dis[x]+a[i].v;
tmp.y
=a[i].y;tmp.dis=dis[a[i].y];
q.push(tmp);
}
}
return dis[n];
}
int main()
{
int i,x,y,w;
cnt
=0;
scanf(
"%d%d",&n,&m);
for(i=1;i<=n;i++)head[i]=-1;
for(i=1;i<=m;i++)
{
scanf(
"%d%d%d",&x,&y,&w);
ad(x,y,w);
}
int ans=dijkstra();
printf(
"%d\n",ans);
}

  

转载于:https://www.cnblogs.com/mjc467621163/archive/2011/07/17/2108526.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值