//dijkstra入门//求最短路径//poj2387//Til the Cows Come Home

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

一个离散数学里学过的求最短路径的算法,虽然听起来很复杂很抽象,但是实现起来也没那么难。
这道题就是没有任何变形的dijkstra模板,但是比较坑爹的一点是,可能出现重边的情况,就是同一条边给了多个值,输入的时候需要处理一下,只保留最小值。
我一开始不知道还有这种坑,就一直WA。
因为路都是双向的,所以1-n的最短路径和n-1的相同,把1作为起点比较方便,所以就从1-n。

#include<stdio.h>
#include<memory.h>

int road[1005][1005];
int dis[1005],visit[1005];//visit是记录哪些点已经加入集合

int main()
{
    int i,j,t,n,start,end,len,cnt,cur,min,minx;
    scanf("%d%d",&t,&n);
    //初始化road
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(i==j) road[i][j]=0;//一个点到自己的距离是0
            else road[i][j]=0x3f3f3f3f;//不存在边的两点间距离记为无穷
        }
    }
    //输入,为road填入值
    for(i=1;i<=t;i++)
    {
        scanf("%d%d%d",&start,&end,&len);
        if(road[start][end]>len)//可能有重边的情况,取最小值
        {
            road[start][end]=len;
            road[end][start]=len;//因为路是双向的
        }
    }
    //初始化dis和visit
    for(i=1;i<=n;i++)
    {
        dis[i]=road[1][i];
    }
    memset(visit,0,sizeof(visit));
    visit[1]=1;//把1加入集合
    cnt=1;//集合中已经有1个数
    cur=1;//当前处理的是1
    //开始dijkstra
    while(cnt!=n)//n个数都加入集合后,退出循环
    {
        min=0x3f3f3f3f;
        for(int i=1;i<=n;i++)
        {
            if(dis[cur]+road[cur][i]<dis[i])
                dis[i]=dis[cur]+road[cur][i];//更新最短路径
            if(visit[i]==0&&dis[i]<min)//找出不再集合中且与1距离最小的点
            {
                min=dis[i];
                minx=i;
            }
        }
        visit[minx]=1;//把这个点加入集合
        cur=minx;//开始处理这个点
        cnt++;//集合中点的个数加1
    }
    printf("%d\n",dis[n]);
}

猜你喜欢

转载自blog.csdn.net/lydia_ke/article/details/79429264
今日推荐