POJ 2387 Til the Cows Come Home 最短路

题目连接

Til the Cows Come Home
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 66264   Accepted: 22300

Description

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

Hint

INPUT DETAILS:

There are five landmarks.

OUTPUT DETAILS:

Bessie can get home by following trails 4, 3, 2, and 1.

Source

题意:输入第一行T和N。T表示有T条道路,N表示有N个城市,分别为城市1,城市2......城市N。接下来输入N行,每行3个数(不妨这三个数用a,b,c表示),表示a和b两个地区有一条长度为c的路。要求输出城市1到城市N的最短路程。

思路:Dijkstra最短路问题。将城市看作点,道路看成边。如果用Floyd算法的话,复杂度为O(n的3次方),妥妥的超时。附上一位大牛的关于Dijkstra算法和Floyed算法的讲解http://blog.51cto.com/ahalei/1387799   http://blog.51cto.com/ahalei/1383613 。讲的真的超级详细,并且容易懂。

关于这道题,一些细节应该注意:1、这是一个双向图;2、并且两个结点之间可能有多条边。

还有就是我开始也是WA了,看了一些人的博客,说这道题的数据并不像题中说的那样,题中说边的长度不大于100,但实际上不是这样的,所以INF开大些就好了。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define maxn 999999
using namespace std;
int e[10100][10100]; //数组e[i][j]表示点i到点j的距离
int dis[101000];     //数组dis[i]表示第一个城市到第i个城市的距离,题目要输出的就是dis[n]
int book[101000];    //book[i]用来标记i这个点是否找到过
int main()
{
    int t,n;
    cin>>t>>n;
    int a,b,c;
    int inf=100000000,minn;//边的长度并不一定小于100,inf要开大些
    for(int i=0;i<=n;i++)
        for(int j=0;j<=n;j++)
            e[i][j]=inf;
    for(int i=1;i<=n;i++)
        e[i][i]=0;
    for(int i=1;i<=t;i++)
    {
        cin>>a>>b>>c;
        if(c<e[a][b])     //连个两点之间有多条,要判断哪个边更小,取较小的边
            e[a][b]=e[b][a]=c;//这是一个无向图,所以两面都要更新
    }
    memset(book,0,sizeof book);
    dis[1]=0;
    for(int i=2;i<=n;i++)
        dis[i]=e[1][i];
    book[1]=1;
    //上边主要是对数据的初始化
    //下边是Dijkstra算法的精髓部分
    for(int i=1;i<=n-1;i++)
    {
        minn=inf;
        int u;
        for(int j=1;j<=n;j++)//在其余未访问过的点中找与第一个点最近的点,记为u
        {
            if(dis[j]<minn&&book[j]==0)
            {
                minn=dis[j];
                u=j;
            }
        }
        book[u]=1;
        for(int j=1;j<=n;j++)
        {
            if(e[u][j]<inf)
                if(dis[j]>dis[u]+e[u][j])
                    dis[j]=dis[u]+e[u][j];
        }
    }
    cout<<dis[n]<<endl;
    return 0;
}

本人菜鸟一个,哪里写的不对或者不合适,欢迎指正,谢谢!

(关于Dijkstra算法部分,如果哪里看不懂可以点开上边那个链接,是位大牛的讲解,或者可以联系我)

我的QQ:1938384271


猜你喜欢

转载自blog.csdn.net/flyzer/article/details/79919377