zoukankan      html  css  js  c++  java
  • 博客作业06--图

    博客作业06--图

    1.学习总结(2分)

    1.1图的思维导图

    1.2 图结构学习体会

    谈谈你对图结构中的几个经典算法学习体会。具体有:

    1.深度遍历算法
    深度遍历理解起来还是比较好理解的,但是翻译成代码,却有点困难,基本上是照搬课本上的代码,其实最重要的是理解递归的思想,然后就是些代码的基本套路了,多读基本就能理解了。

    2.广度遍历算法
    广度遍历与深度遍历基本上是同一个模板的东西,只是不同于递归而是用了队列,跟树的遍历基本差不多,学习来比深度简单,但是代码要更多。

    3.Prim和Kruscal算法
    这两种算法都是生成最小二叉树的方法,这两种方法的基本思想能理解,就是从待选的边中找最小的边加入,但是代码实现的话,只用过prim算法,跟着课本些的,想了很久才理解了代码的实现,而且不知道课本上的代码有什么问题,pta的一道题中有一个点始终过不了,后来网上找了另一中prim算法,才过了,而Kruscal算法则没有用代码实现过,还是有点生疏。

    4.Dijkstra算法
    写这个算法的时候,发现其实根prim算法有点相似,都是初始化,找最小,更新,这种思路往下写的,不过特别的一点是,可以找到整条路径,但是思路也都差不多。

    5.拓扑排序算法
    这个算法就相对前面的算法相对简单,思路好理解,代码实现的话,有了前面的基础,写起来也是相对较简单的。

    2.PTA实验作业(4分)

    题目1:7-1 图着色问题

    设计思路(伪代码或流程图)

    主函数:
    定义一个int类型的set s
    输入图节点数,边数和颜色数
    用creatMGraph建一个图
    输入待检测的涂色方案数v
    for i=0 to v
        输入涂色方案
        清空set
        通过放到set的颜色数比较是否正确
        if(set中的颜色数正确)
            通过Judge函数判断涂色方案是否正确
            if(返回1)输出yes
            else 输出no
        else
            输出no
    end
    
    
    Judge函数:
    for i=0 to n
        for j=0 to n
            if(矩阵中存有边)
                if(边两个端点的颜色一样)
                    返回0
        end
    end
    返回1
    
    
    

    代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

    PTA提交列表说明。

    刚开始打算用邻接表做,写了好久,刚开始是MAXV的值设置的太小,导致运行错误,后来没有考虑到联通图与非联通图的判断,后来慢慢改只能如果就差一个卡DFS不重复访问顶点的错误实在是不懂什么意思,问了同学,他说使用邻接矩阵做的,没遇到这个错误,而且更简单,于是我干脆直接全改成了矩阵,花了一会而就都过了。

    题目2:7-3 六度空间

    设计思路(伪代码或流程图)

    主函数:
    输入节点数,边数建一个图
    遍历每一个节点
        用BFS函数计算每个节点距离不超过6的结点数
        节点数出总数,输出
    
    BFS函数:
    定义数组visited存节点是否遍历
    定义队列q
    定义last存每层的最后一个节点
    last初始等于待计算的节点v
    初始visited数组
    visited【v】=1,表示v已访问过
    v入队
    while(队列不空)
        取出队首元素
        for i=1 to n
            if(该元素未访问且跟i有边)
                入队
                visited数组中该元素标记为已访问
                cnt++
                定义tail记录最后存入队列的元素
        end
        if(v==last)
            level++
            更新last等于last
        if(level等于6)结束循环
    end
    返回cnt
    
    

    代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

    PTA提交列表说明。

    这道题理解了思路后就会发现还是挺好做的,但是不清楚MAX的值才会提交了好多次。

    题目3:7-6 修建道路

    设计思路(伪代码或流程图)

    主函数:
    输入n建立矩阵
    通过矩阵建图
    输入v
    for i=0 to v
        输入两个端点
        在邻接矩阵中把原来的边数变成1
    end
    调用Prim函数返回最小的生成树边的值
    输出生成树的减v
    
    
    Prim:
    
    定义lowcost数组和closest数组
    初始化这两个数组
    for j=2 to n
        找最小的边数
        存下最小边数和节点
    end
    cnt+=min,way++
    更新lowcost数组和closest数组
    返回cnt
    
    

    代码截图(注意,截图、截图、截图。代码不要粘贴博客上。不用用···语法去渲染)

    PTA提交列表说明。

    刚开始完全找不到思路怎么写,后来写了一个版本出来,结果只对了一个点,后来就完全找不到错误要怎么改,当时思路太乱,根本不知道怎么改。后来在舍友哪里听到了这个题目的类似取巧的方法,具体就是将已经修建的道路权值改写为1,所以在计算时权值为1的路就会作为最小的路径计算进去,只要到最后减掉修建的路数就可以,结果写了一下就对了。

    3.截图本周题目集的PTA最后排名(3分)

    3.1 PTA排名(截图带自己名字的排名)

    3.2 我的总分:310

    4. 阅读代码(必做,1分)

    图的最短路径问题-Floyd算法-07-图4 哈利·波特的考试
    哈利·波特要考试了,他需要你的帮助。这门课学的是用魔咒将一种动物变成另一种动物的本事。例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等。反方向变化的魔咒就是简单地将原来的魔咒倒过来念,例如ahah可以将老鼠变成猫。另外,如果想把猫变成鱼,可以通过念一个直接魔咒lalala,也可以将猫变老鼠、老鼠变鱼的魔咒连起来念:hahahehe。

    现在哈利·波特的手里有一本教材,里面列出了所有的变形魔咒和能变的动物。老师允许他自己带一只动物去考场,要考察他把这只动物变成任意一只指定动物的本事。于是他来问你:带什么动物去可以让最难变的那种动物(即该动物变为哈利·波特自己带去的动物所需要的魔咒最长)需要的魔咒最短?例如:如果只有猫、鼠、鱼,则显然哈利·波特应该带鼠去,因为鼠变成另外两种动物都只需要念4个字符;而如果带猫去,则至少需要念6个字符才能把猫变成鱼;同理,带鱼去也不是最好的选择。

    输入格式:

    输入说明:输入第1行给出两个正整数N (≤100)和M,其中N是考试涉及的动物总数,M是用于直接变形的魔咒条数。为简单起见,我们将动物按1~N编号。随后M行,每行给出了3个正整数,分别是两种动物的编号、以及它们之间变形需要的魔咒的长度(≤100),数字之间用空格分隔。

    输出格式:

    输出哈利·波特应该带去考场的动物的编号、以及最长的变形魔咒的长度,中间以空格分隔。如果只带1只动物是不可能完成所有变形要求的,则输出0。如果有若干只动物都可以备选,则输出编号最小的那只。

    输入样例:
    6 11
    3 4 70
    1 2 1
    5 4 50
    2 6 50
    5 6 60
    1 3 70
    4 6 60
    3 6 80
    5 1 100
    2 4 60
    5 2 80

    输出样例:
    4 70

    #include<iostream>
    using namespace std;
    
    #define INFINITY 123456
    #define MAXN 101
    
    int Graph[MAXN][MAXN];
    int dist[MAXN][MAXN];
    int N,M;
    
    //Floyd算法求最短路径 
    void Flody() 
    {
        int k,i,j;
        for(k=1; k<=N; k++){
            for(i=1; i<=N; i++){
                for(j=1; j<=N; j++){
                    if(dist[i][k] + dist[k][j] < dist[i][j]){
                        dist[i][j] = dist[i][k] + dist[k][j];
                    }
                }
            }
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("hali.txt","r",stdin);
        #endif
    
        int i, j, x, y, weight;
    
        scanf("%d%d", &N, &M);
    
        //初始化图数组
        for(i=1; i<=N; i++){
            for(j=1; j<=N; j++){
                if(i == j)  Graph[i][j] = 0;
                else        Graph[i][j] = INFINITY;
            }
    
        }
        //读取数据 
        for(i=1; i<=M; i++){
            scanf("%d%d%d", &x, &y, &weight);
            Graph[x][y] = weight;
            Graph[y][x] = weight;
        }
    
        //初始化距离数组
        for(i=1; i<=N; i++){
            for(j=1; j<=N; j++){
                dist[i][j] = Graph[i][j];
            }
    
        }
    
        Flody();
    
        int minAnimal = -1, minDist = INFINITY;
        for(i=1; i<=N; i++){
            int tmp = 0;
            for(j=1; j<=N; j++){
                if(dist[i][j] > tmp)    tmp = dist[i][j];
            }
    
            if(tmp == INFINITY){
                printf("0
    ");
                return 0;
            }
            //printf("%d
    ",i);
            if(tmp < minDist){
                minAnimal = i;
                minDist = tmp;
            }
        }
        printf("%d %d
    ", minAnimal, minDist);
        return 0;
    } 
    
    

    题目看起来特别的复杂,但是如果把动物看成图的顶点,魔咒的长度看成是顶点之间的权重的话,那么题目就变成了。求最短路径问题了。
    这题用的是弗洛伊德算法来计算最短路径的问题,主干函数也就只有几行的代码,简单明了,值得借鉴。

  • 相关阅读:
    ztree : 增删改功能demo与自定义DOM功能demo的结合
    CF786B Legacy 线段树优化建图
    UVA11992 Fast Matrix Operations 一次开多棵线段树
    P3950 部落冲突 树链剖分
    洛谷P1471 方差 线段树维护区间方差
    2019.7.26 T1 树剖+双标记
    P1505 [国家集训队]旅游
    NOIP2015 运输计划 树上差分+树剖
    P1373 小a和uim之大逃离 四维dp,维护差值
    Pyhton之subprocess模块和configparser模块
  • 原文地址:https://www.cnblogs.com/doimpossible/p/9161927.html
Copyright © 2011-2022 走看看