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

来源:互联网 发布:淘宝砖石卖家信誉好吗 编辑:程序博客网 时间:2024/06/08 15:33
Problem Description某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。Input本题目包含多组数据,请处理到文件结束。 每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0N-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 Input3 30 1 10 2 31 2 10 23 10 1 11 2Sample Output2-1AuthorlinleSource2008浙大研究生复试热身赛(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[N],ans;vector<Edge>G[N];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[N],ans;vector<Edge>G[N];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;}
原创粉丝点击