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

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

Input
本题目包含多组数据,请处理到文件结束。 每组数据第一行包含两个正整数N和M(0<N<200,01000),
分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0N-1编号。 接下来是M行道路信息。
每一行有三个整数A,B,X(0<=A,B<N,A!=B,010000),表示城镇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了,但是在原题处提交显示编译错误
这里写图片描述
(hdu1874)畅通工程续(dijkstra算法)_第1张图片
由于初用构造函数,没有详细了解,紫书P106有介绍,这个优先队列里用到了greater

,这是在挑战程序设计竞赛上看的,但是报错没懂,不会就不要瞎用!这里是因为少了头文件#include。加上这个就可以AC,不过用优先队列不太习惯,下面的一种直接重载就行了

#include
#include
#include
#include
#include
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;
vectorG[N];
void dij(int s,int y)
{
    priority_queuevector

,greater

>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]continue; if(v==y) { ans=d[v]; break; } for(int i=0; iif(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; ifor(int i=0; iscanf("%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
#include
#include
#include
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;
vectorG[N];
void dij(int s,int y)
{
    priority_queuepq;
    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]///当前距离不是最短的,丢弃
            continue;
        if(v==y)///到达终点,停止扩展,跳出循环
        {
            ans=d[v];
            break;
        }
        for(int i=0; iif(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; ifor(int i=0; iscanf("%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;
}

你可能感兴趣的:(ACM_图论问题,HDU)