[POJ](2387)Til the Cows Come Home---单源最短路径(图)

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

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


注:加权无向图

ac代码:Dijkstra's Algorithm(狄克斯特拉算法)

参考:①:http://blog.csdn.net/riba2534/article/details/54428324

②:http://www.wutianqi.com/?p=1890

③:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

#include<iostream>
#include<cstring>
using namespace std;
const int inf=1<<29;//无限大变量
int t,n;//t为顶点个数,n表示求顶点1->n的最短路径
int u,v,w;//两个顶点u,v,权值w
int mmin;
int k;
int dist[2005];//从源点到i的距离
bool vis[2005];//用来标记该顶点是否被访问过
int mmap[2005][2005];//顶点i到顶点j的距离
void dijkstra(int n)
{
    mmin=0;
    for(int i=1;i<=n;i++)
    {
        dist[i]=mmap[1][i];//先确定源点1到每个顶点的距离
    }
    for(int i=1;i<=n;i++)//对图进行遍历
    {
        k=0;
        mmin=inf;
        for(int j=1;j<=n;j++)
        {
            if(!vis[j] && dist[j]<mmin)//寻找到顶点i到j的最短路径
            {
                mmin=dist[j];
                k=j;//若找到,更新从i到j的最短路径,储存当前j顶点  // <---抽象这部分循环,其实就是在往最短路径树
             }                                                     //  中抽象地添加顶点                   
        }
        vis[k]=true;
        for(int j=1;j<=n;j++)
        {
            if(!vis[j] && dist[k]+mmap[k][j]<dist[j])
                dist[j]=dist[k]+mmap[k][j]; //dist[x]记录着仅经由最短路径树集合S内顶点到达顶点x的最短路径成本
        }
    }
}
int main()
{
    memset(dist,0,sizeof(dist));
    memset(vis,false,sizeof(vis));
    memset(mmap,0,sizeof(mmap));
    cin>>t>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
            mmap[i][j]=inf;//初始化图的顶点之间的距离为无限大
    }
    for(int i=1;i<=t;i++)//有t个顶点
    {
        cin>>u>>v>>w;
        if(w<mmap[u][v])
        {
            mmap[u][v]=w;
            mmap[v][u]=mmap[u][v];//建立无向图,这里借鉴了别人的算法,因为最短路径有一个坑点,即两个顶点之间有重边
        }
    }
    dijkstra(n);
    cout<<dist[n]<<endl;
    return 0;
}

总结:关于图的算法真的是太奥妙了,让我对前人的算法叹为观止。感觉Dijkstra算法就是一种贪心的策略,这种算法是最经典的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点就是以起始点为中心向外层层扩展,以最短为策略,直到扩展到终点为止。

posted @ 2017-08-08 15:59  WangMeow  阅读(183)  评论(0编辑  收藏  举报