• POJ 2387 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
      Hint
      INPUT DETAILS:

    There are five landmarks.

    OUTPUT DETAILS:

    Bessie can get home by following trails 4, 3, 2, and 1.
    题意:给你一个t和n,代表t条边,n为最大顶点编号;
    然后t组数据,分别是u,v,w;
    点u,点v,点u和点v的距离w;
    求起点到终点的距离(样例中就是1到5)。
    代码已经明确注释

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    #include<math.h>
    #include<queue>
    using namespace std;
    const int maxn=1005;
    const int INF=0x3f3f3f3f;//记住开三个数组
    int map[maxn][maxn];//邻接矩阵记录地图
    int dis[maxn];//记录(起点——maxn的距离)最短路
    int vis[maxn];//初始化为0,已访问标记为1
    int T;//边的数量
    int N;//最大顶点编号,求N到1最短路
    void Dijkstra()
    {
    //第四步,所有的路先全标记没走过,再标记出发点走过
        memset(vis,0,sizeof(vis));
        vis[1]=1;
        //第五步,记录距离出发点的距离
        for(int i=1; i<=N; i++)
            dis[i]=map[1][i];//记录从起点到i点的距离(有的不知道,因为没有不挨着)
        for(int i=1; i<N; i++)//接下来求那些不挨着的点的最短路
        {
            int minn=INF;
            int point;
            for(int j=1; j<=N; j++)//第六步,寻找到所有知道的路径中的最短的一条
                if(vis[j]==0&&dis[j]<minn)//那么为什么要找最短的一条呢?
                {
                    minn=dis[j];//很明显,当然是为了实现那些不挨着的点的路到起点最短啊
                    point=j;//记录这个点的位置
                }
                //第七步,标记
            vis[point]=1;//标记这个点已经走过
            for(int j=1; j<=N; j++)
            {
            //第八步,
                if(map[point][j]<INF&&dis[point]+map[point][j]<dis[j])
                    //第一个判断point到j是否小于INF,不小于就没有下一步判断了,(无穷大的距离有卵用)
                    //第二个判断起点到point的距离+point到j的距离是否比短的更短,如果更短,当然要这个了
                    //dis[j]是为了记录最短路嘛
                    dis[j]=dis[point]+map[point][j];
            }
        }
    }
    int main()
    {
        scanf("%d%d",&T,&N);
        for(int i=0; i<=N; i++) //第一步,初始化矩阵
            for(int j=0; j<=N; j++)
                i==j?map[i][j]=0:map[i][j]=INF;//自己到自己的距离为0,其他不知,初始化为无穷大(learning)
        while(T--)//第二步,接下来实现存图
        {
            int u,v,w;//u,v是点,w是两点间的距离
            scanf("%d%d%d",&u,&v,&w);
            if(w<map[u][v])//这一判断是为了防止重边,例如:1到2是20,2到1是30
            {
                map[u][v]=w;//因为此题为无向图
                map[v][u]=w;//所以u到v,和v到u的距离是一样的
            }
        }
        //第三步,开始计算最短路
        Dijkstra();
        printf("%d
    ",dis[N]);//起点到终点的最短路
        return 0;
    }
    

    又复习了一下,理解更加深刻了
    把算法转化为自己的思想才是最重要的
    要转化为自己的思想,就要深刻理解

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define mem(a) memset(a,0,sizeof(a))
    const int maxn=2005;
    const int INF=0x3f3f3f3f;
    int mapp[maxn][maxn];
    int dis[maxn];
    int vis[maxn];
    int t,n;
    int Dijkstra()
    {
        for(int i=1; i<=n; i++)
            dis[i]=mapp[1][i];
        vis[1]=1;
        for(int i=1; i<t; i++)
        {
            int point=0,maxx=INF;
            for(int j=1; j<=n; j++)
                if(vis[j]==0&&dis[j]<maxx)
                    maxx=dis[j],point=j;//求没走过且从起点道j的最短的一条路
            vis[point]=1;
            for(int j=1; j<=n; j++)
                dis[j]=min(dis[j],dis[point]+mapp[point][j]);//最短那条路加上到其他点最短边,
                更新起点到其他点的最短距离
        }
    }
    int main()
    {
        while(~scanf("%d%d",&t,&n))
        {
            mem(mapp);
            mem(dis);
            mem(vis);
            for(int i=0; i<=n; i++)
                for(int j=0; j<=n; j++)
                    i==j?mapp[i][j]=0:mapp[i][j]=INF;
            int u,v,w;
            for(int i=1; i<=t; i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                if(w<mapp[u][v])//这点尤其要注意,防重
                    mapp[u][v]=mapp[v][u]=w;
            }
            Dijkstra();
            printf("%d
    ",dis[n]);
        }
        return 0;
    }
    
    "No regrets."
  • 相关阅读:
    对象方法Android之多媒体使用——MediaPlayer播放音频
    程序函数C语言中异常处理的两个函数
    退出窗口[置顶] 退出Activity的方法
    循环变量hdu 1799 循环多少次?
    网页剪辑有道云笔记、印象笔记(evernote)哪个更好?
    选项选择Windows XP系统安装MySQL5.5.28图解
    修改nullMyEclipse 设置文件的默认编码
    文件应用iOS开发用keychain替代UDID
    模块执行python模块介绍 struct 二进制数据结构
    数据库字符串AVP(AttributeValue Pair)
  • 原文地址:https://www.cnblogs.com/zxy160/p/7215172.html
Copyright © 2020-2023  润新知