您的位置:首页 > 其它

(hdu1874)畅通工程续(dijkstra算法)

2017-07-22 09:43 239 查看
Problem Description
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,
每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案
要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。

Input
本题目包含多组数据,请处理到文件结束。 每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),
分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。 接下来是M行道路信息。
每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的
双向道路。 再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。

Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.

Sample Input
3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2

Sample Output
2
-1

Author
linle
Source
2008浙大研究生复试热身赛(2)——全真模拟


分析:起点和终点是定点,所以是两点间的最短路问题,故用dijkstra算法+优先队列。

代码:第一份代码在hd专题里AC了,但是在原题处提交显示编译错误





由于初用构造函数,没有详细了解,紫书P106有介绍,这个优先队列里用到了greater
<P>
,这是在挑战程序设计竞赛上看的,但是报错没懂,不会就不要瞎用!这里是因为少了头文件
#include<functional>
。加上这个就可以AC,不过用优先队列不太习惯,下面的一种直接重载就行了

#include<cstdio>
#include<queue>
#include<cstring>
#include<functional>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=205;
int n,m;
typedef struct Edge
{
int to,w;
Edge(int a,int b) :to(a),w(b){}
};
typedef pair<int,int >P;
int v,d
,ans;
vector<Edge>G
;
void dij(int s,int y)
{
priority_queue<P,vector<P>,greater<P> >pq;
memset(d,INF,sizeof(d));
d[s]=0;
pq.push(P(0,s));
while(!pq.empty())
{
P p=pq.top();
pq.pop();
int v=p.second;
if(d[v]<p.first)
continue;
if(v==y)
{
ans=d[v];
break;
}
for(int i=0; i<G[v].size(); i++)
{
Edge e=G[v][i];
if(d[e.to]>d[v]+e.w)
{
d[e.to]=d[v]+e.w;
pq.push(P(d[e.to],e.to));
}
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(d,INF,sizeof(d));
int a,b,w;
for(int i=0; i<n; i++)
G[i].clear();
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&a,&b,&w);
G[a].push_back(Edge(b,w));
G[b].push_back(Edge(a,w));
}
int s,tar;
scanf("%d%d",&s,&tar);
ans=INF;
dij(s,tar);
if(ans==INF)
printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}


代码2.

这份已AC

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1005;
int n,m;
typedef struct Edge
{
int to,w;
Edge(int a,int b) :to(a),w(b) {}///构造函数。。
bool operator < (const Edge &m)const///重载<运算符
{
return w>m.w;///按权值w从小到大排序
}
};
int v,d
,ans;
vector<Edge>G
;
void dij(int s,int y)
{
priority_queue<Edge>pq;
memset(d,INF,sizeof(d));
d[s]=0;
pq.push(Edge(s,d[s]));///这里用到了结构体中的构造函数
while(!pq.empty())
{
Edge p=pq.top();
pq.pop();
int v=p.to;
if(d[v]<p.w)///当前距离不是最短的,丢弃
continue;
if(v==y)///到达终点,停止扩展,跳出循环
{
ans=d[v];
break;
}
for(int i=0; i<G[v].size(); i++)
{
Edge e=G[v][i];
if(d[e.to]>d[v]+e.w)///dijkstra的核心
{
d[e.to]=d[v]+e.w;
pq.push(Edge(e.to,d[e.to]));
}
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int a,b,w;
for(int i=0; i<n; i++)
G[i].clear();
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&a,&b,&w);
G[a].push_back(Edge(b,w));//加入不定数组G,a->b的路长为w
G[b].push_back(Edge(a,w));//b->a的路长也为w,路是双向的
}
int s,tar;
scanf("%d%d",&s,&tar);
ans=INF;
dij(s,tar);
if(ans==INF)///没有路到达终点
printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息