(kuangbin带你飞--最短路径)Til the Cows Come Home POJ2387

原题目:

Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the morning milking. Bessie needs her beauty sleep, so she wants to get back as quickly as possible.

Farmer John's field has N (2 <= N <= 1000) landmarks in it, uniquely numbered 1..N. Landmark 1 is the barn; the apple tree grove in which Bessie stands all day is landmark N. Cows travel in the field using T (1 <= T <= 2000) bidirectional cow-trails of various lengths between the landmarks. Bessie is not confident of her navigation ability, so she always stays on a trail from its start to its end once she starts it.

Given the trails between the landmarks, determine the minimum distance Bessie must walk to get back to the barn. It is guaranteed that some such route exists.

Input:

* Line 1: Two integers: T and N

* Lines 2..T+1: Each line describes a trail as three space-separated integers. The first two integers are the landmarks between which the trail travels. The third integer is the length of the trail, range 1..100.

Output

* Line 1: A single integer, the minimum distance that Bessie must travel to get from landmark N to landmark 1.

Sample Input

5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100

Sample Output

90

中文概要:就是开始给你两个数T跟N,T表示有多少行,N表示有多少个点,下面每一行表示两点之间的距离,最后求的1点到最后一点的最短路径。


#include<stdio.h>

#define Max 0x3fffffff

int map[1005][1005];

int dis[1005];

void dijkstra(int n)

{

    int visit[1001]={0};

    int min,i,j,k;

    visit[1]=1;

    for(i=1;i<n;++i)

    {

        min=Max;

        k=1;

        for(j=1;j<=n;++j)

        {

            if(!visit[j]&&min>dis[j])

            {

                min=dis[j];

                k=j;

            }

        }

        visit[k]=1;

        for(j=1;j<=n;++j)

        {

            if(!visit[j]&&dis[j]>dis[k]+map[k][j])

                dis[j]=dis[k]+map[k][j];

        }

    }

    printf("%d\n",dis[n]);

}

int main()

{

    int t,n,i,j,from,to,cost;

    while(scanf("%d%d",&t,&n)!=EOF)

    {

        for(i=1;i<=n;++i)

        {

            map[i][i]=0;

            for(j=1;j<i;++j)

                map[i][j]=map[j][i]=Max;

        }

        for(i=1;i<=t;++i)

        {

            scanf("%d%d%d",&from,&to,&cost);

            if(cost<map[from][to])                //可能有多条路,只记录最短的

                map[from][to]=map[to][from]=cost;

        }

        for(i=1;i<=n;++i)

            dis[i]=map[1][i];

        dijkstra(n);

    }

}

思路:

(Dijkstra算法)

最经典最基础的Dijkstra算法,昨天看半天猜的思路,今天具体看看好像差不多,但是在main函数中一定要先把题目给出的图论要转化成二维数组map[x][x],转成邻接矩阵。

(Dijkstra算法描述)

        算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
算法步骤:
        a.初始时,S只包含源点,即S={v},v的距离为0。U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,若u不是v的出边邻接点,则<u,v>权值为∞。
        b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。
        c.以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。
        d.重复步骤b和c直到所有顶点都包含在S中。

PS:今天只是基本懂得Dijkstra的原理,但是还要经过好几天的题目练习才能真正明白精髓,还有两个算法没看。。。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

deebcjrb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值