图论入门题题解

news2024/11/17 0:47:10

✨欢迎来到脑子不好的小菜鸟的文章✨

      🎈创作不易,麻烦点点赞哦🎈

          所属专栏:刷题_脑子不好的小菜鸟的博客-CSDN博客

          我的主页:脑子不好的小菜鸟

          文章特点:关键点和步骤讲解放在

          代码相应位置

拓扑排序 / 家谱树
https://vjudge.net/contest/613618#problem/A


//拓扑排序:找到入度为0的点,将其写入答案,再删去其箭头,再继续找入度为0的点,循环往复

vector<int>edeg[101];
int n, deg[101] = { 0 };//入度
void init()//建图
{
    cin >> n;
    int i, val;
    for (i = 1; i <= n; i++)
    {
        while (cin >> val && val != 0)
        {
            edeg[i].push_back(val);
            deg[val]++;
        }
    }
}

void toposort()//拓扑排序
{
    int i;
    queue<int> que;
    for (i = 1; i <= n; i++)
    {
        if (deg[i] == 0)
        {
            cout << i << ' ';
            que.push(i);
        }
    }

    while (!que.empty())
    {
        int t = que.front();
        que.pop();

        for (int i : edeg[t])
        //相当于i表示edeg[t]的第一个元素,进行一次循环后就是第二个元素,循环往复
        {
            deg[i]--;
            if (deg[i] == 0)
            {
                cout << i << ' ';
                que.push(i);
                //push的原因:可能i(也就是edeg[t])还有箭头指向其他的数,也就是后面辈分比它小的,要通过i来找比它辈分小的
            }
        }
    }
}

int main()
{
    init();//建图
    toposort();//拓扑排序
    return 0;
}

P3371 【模板】单源最短路径(弱化版)
https://www.luogu.com.cn/problem/P3371

///*法一:邻接矩阵*/
占的空间较多,时间复杂度较大,不适合


/*法二:结构体,堆优化*/
//要一个结构体,存一个点相关的东西(to, wei, next)(终点, 权值, 下一个儿子)
//cnt:结构体下标
//head[MAX]:head[i]:查找i点的第一个儿子
//pos:将被标记的值
//ans[MAX]:最短距离
//visit[MAX]:是否被标记过

//题解:https://www.luogu.com.cn/article/oswxjzrl
#include <iostream>#include <climits>
using namespace std;
const int MAX = 1e6;int cnt;//结构体下标int visit[MAX];//标记int n, m, s;int head[MAX];//存放儿子int ans[MAX];//放到起点的最短距离
struct EDGE
{
    int wei;//权值
    int to;//目的地
    int next;//下一个儿子
}edge[MAX];
void add(int u, int v, int w){
    cnt++;
    edge[cnt].wei = w;
    edge[cnt].to = v;
    edge[cnt].next = head[u];//将下一个儿子记录
    head[u] = cnt;//更新第一个儿子
}
int main(){
    cin >> n >> m >> s;
    int i;

    //初始化ans
    for (i = 1; i <= n; i++)
        ans[i] = INT_MAX;

    ans[s] = 0;

    int u, v, w;
    for (i = 1; i <= m; i++)
    {
        cin >> u >> v >> w;
        add(u, v, w);
    }

    int pos = s;//初始化pos为s
    while (visit[pos] == 0)
    {
        int minn = INT_MAX;//注意更新
        visit[pos] = 1;//标记

        //更新儿子的最短路径
        for (i = head[pos]; i != 0; i = edge[i].next)
        {
            if (visit[edge[i].to] == 0 && ans[edge[i].to] > ans[pos] + edge[i].wei)
                ans[edge[i].to] = ans[pos] + edge[i].wei;
        }

        //找最短路径
        for (i = 1; i <= n; i++)
        {
            if (visit[i] == 0 && ans[i] < minn)
            {
                minn = ans[i];
                pos = i;
            }
        }
    }

    for (i = 1; i <= n; i++)
        cout << ans[i] << ' ';
    cout << endl;
    return 0;
}

P4779 【模板】单源最短路径(标准版)
https://www.luogu.com.cn/problem/P4779

注意:该题用上一题的代码会超时,因此要用堆优化,也就是优先队列



//友情提示:正权图  请  使用dijkstra算法,   负权图  请  使用SPFA算法

//弱化版的代码超时---->要用堆优化
/*
核心:priority_queue< pair<int,int> > 用优先队列来取最近的点,就不用遍历找点了

在pq中,是按pair的第一个元素(first)由大到小排序的,所以pair<距离,点号>,注意因为要的是最小值,所以距离要存负值
其实距离是纯纯的工具人,我们只是需要它来维持点的排序

每次取队首h,取出的就是dis最短的点
还要注意:
如果这个点的dis不等于h的dis,说明这个点在入队之后被更新了,那么我们就不用这个点了,直接continue;
因为后面会有个h2点比h1的dis更小,用h1更新就没有意义了
*/

//使用优先队列,注意:优先队列是从大到小排列,所以存进去应该存负数

C代码:
#include <queue>
/*堆优化:利用优先队列,降低复杂度,直接排序,注意优先队列是由大到小排列的,因此距离是负数 */
#include <climits>
#include <iostream>

using namespace std;

const int MAX = 1e6;
int n, m, s;
int ans[MAX];
int cnt;
int head[MAX];
int visit[MAX];

struct EDGE
{
    int to;
    int next;
    int wei;
}edge[MAX];

void add(int u, int v, int w)
{
    cnt++;
    edge[cnt].wei = w;
    edge[cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt;
}

int main()
{
    int i;
    int u, v, w;
    cin >> n >> m >> s;

    for (i = 1; i <= n; i++)
        ans[i] = INT_MAX;
    ans[s] = 0;

    for (i = 1; i <= m; i++)
    {
        cin >> u >> v >> w;
        add(u, v, w);
    }

    priority_queue<pair<int, int> >que;//距离,点
    que.push({0, s});

    while (!que.empty())
    {
        int qh = que.top().first;
        int h = que.top().second;
        que.pop();/*记得pop()!!!!!!!!!*/

        if (visit[h] == 0)
        {
            visit[h] = 1;
            for (i = head[h]; i != 0; i = edge[i].next)//不断找下一个儿子,直到找完
            {
                if (ans[edge[i].to] > ans[h] + edge[i].wei)
                {
                    ans[edge[i].to] = ans[h] + edge[i].wei;
                    if (visit[edge[i].to] == 0)
                        que.push({ -ans[edge[i].to], edge[i].to });

                }
            }
        }
    }

    for (i = 1; i <= n; i++)
        cout << ans[i] << ' ';
    cout << endl;
    return 0;
}

B3647 【模板】Floyd
https://www.luogu.com.cn/problem/B3647 



//floyd算法
//要注意中转点,可以直接i到j,也可以i->k,k->j,因此要比较两个数据的大小,最后表中的是最短路径
//注意是无向图

#include <climits>

int main()
{
    int n, m, i, j, u, v, w;
    long long board[105][105] = { 0 };//存最短路径

  

    cin >> n >> m;

    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {
            if (i == j)
                board[i][j] = 0;
            else
               board[i][j] = INT_MAX;
        }
    }

    for (i = 1; i <= m; i++)
    {
        cin >> u >> v >> w;
        if (w < board[u][v])
            board[u][v] = w;
        if (w < board[v][u])
            board[v][u] = w;
    }

    int k;           
    for (k = 1; k <= n; k++)//把k当中转点,注意是放在i,j循环的外面
    {
        for (i = 1; i <= n; i++)//行,列
        {
            if (i == k)
                continue;
            for (j = 1; j <= n; j++)
            {
                if (j == k)
                    continue;

                if (i == j)
                    continue;

                if (board[i][k] != INT_MAX && board[k][j] != INT_MAX)
                    board[i][j] = min(board[i][j], board[i][k] + board[k][j]);

            }
        }
    }

    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {
            cout << board[i][j] << ' ';
        }
        cout << endl;
    }
    return 0;
}

恭喜你啦,今天又进步了一点点~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1501717.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

精读《React Conf 2019 - Day2》

1 引言 这是继 精读《React Conf 2019 - Day1》 之后的第二篇&#xff0c;补充了 React Conf 2019 第二天的内容。 2 概述 & 精读 第二天的内容更为精彩&#xff0c;笔者会重点介绍比较干货的部分。 Fast refresh Fast refresh 是更好的 react-hot-loader 替代方案&am…

推荐一款go语言的开源物联网框架-opengw

推荐一款go语言的开源物联网框架&#xff0c;设计思想不错&#xff0c;值的学习。 技术交流 QQ群1028704210 官网及驱动下载 http://www.opengw.cn http://www.opengw.cn/col.jsp?id104 可执行文件下载 https://gitee.com/my_iot/goAdapter/releases 码云地址 https:/…

excel统计分析——重复测量设计

参考资料&#xff1a;生物统计学 裂区设计中的裂区通常是指空间上的裂区&#xff0c;如果对试验指标进行连续测量时&#xff0c;时间也可以作为裂区因素。重复测量设计实际上就是时间裂区设计。进行试验结果的统计分析时&#xff0c;将试验因素作为主区&#xff0c;时间因素作为…

开源模型应用落地-工具使用篇-Spring AI-高阶用法(九)

一、前言 通过“开源模型应用落地-工具使用篇-Spring AI-Function Call&#xff08;八&#xff09;-CSDN博客”文章的学习&#xff0c;已经掌握了如何通过Spring AI集成OpenAI以及如何进行function call的调用&#xff0c;现在将进一步学习Spring AI更高阶的用法&#xff0c;如…

计算机设计大赛 深度学习验证码识别 - 机器视觉 python opencv

文章目录 0 前言1 项目简介2 验证码识别步骤2.1 灰度处理&二值化2.2 去除边框2.3 图像降噪2.4 字符切割2.5 识别 3 基于tensorflow的验证码识别3.1 数据集3.2 基于tf的神经网络训练代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x…

AutoDev 自定义 Agent:快速接入内部 AI Agent,构建 IDE 即 AI 辅助研发中心

在开源 AI IDE 插件 AutoDev 的 #51 issue 中&#xff0c;我们设计了 AutoDev 的 AI Agent 能力&#xff0c;半年后我们终于交付了这个功能。 在 AutoDev 1.7.0 中&#xff0c;你将可以接入内部的 AI Agent&#xff0c;并将其无缝与现有的 AI 辅助能力结合在一起。 本文将使用 …

Docker_搭建跨服务器网络通讯(swarm 集群)

本文目录 一、如何搭建docker的跨服务器网络1、在主服务器上初始化docker swarm 集群2、其他服务器节点加入到创建好的集群中3、检验集群是否搭建成功4、创建overlay类型的docker网络 二、如何部署服务1、docker部署2、docker-compose部署 一、如何搭建docker的跨服务器网络 1…

c#递归函数

在 C#中&#xff0c;递归函数是指在函数内部直接或间接调用自身的函数。递归函数在解决一些问题时非常有用&#xff0c;例如遍历树形结构、递归计算等。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks…

springboot252基于Springboot和vue的餐饮管理系统的设计与实现

餐饮管理系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&…

打造经典游戏:HTML5与CSS3实现俄罗斯方块

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

移动端精准测试之跨版本覆盖率合并

一&#xff0c;项目简介 在移动端项目测试过程中&#xff0c;尤其是发版前的回归测试阶段&#xff0c;会遇到这样的情况&#xff0c;在测试过程中测试不断地发现问题&#xff0c;开发就进行修改&#xff0c;然后打包测试。而测试完成后呢&#xff0c;业务测试同学想知道整个回归…

Xcode升级到Xcode15.1或15.2之后,无法新建Category和Extension文件,如何解决?

项目场景&#xff1a; Xcode升级到15.1或15.2之后&#xff0c;无法新建Category和Extension文件&#xff0c;并且Xcode不报任何错误 问题描述 Xcode升级到15.1或15.2之后&#xff0c;无法新建Category和Extension文件&#xff0c;并且Xcode不报任何错误。 具体的操作步骤如下…

UDP实现文件的发送、UDP实现全双工的聊天、TCP通信协议

我要成为嵌入式高手之3月7日Linux高编第十七天&#xff01;&#xff01; ———————————————————————————— 回顾 重要程序 1、UDP实现文件的发送 发端&#xff1a; #include "head.h"int main(void) {int sockfd 0;struct sockaddr_i…

缩放算法优化步骤详解

添加链接描述 背景 假设数据存放在在unsigned char* m_pData 里面&#xff0c;宽和高分别是&#xff1a;m_nDataWidth m_nDataHeight 给定缩放比例&#xff1a;fXZoom fYZoom&#xff0c;返回缩放后的unsigned char* dataZoom 这里采用最简单的缩放算法即&#xff1a; 根据比…

【C语言】数据类型和变量

前言&#x1f49e;&#x1f49e; 啦啦啦~这里是土土数据结构学习笔记&#x1f973;&#x1f973; &#x1f4a5;个人主页&#xff1a;大耳朵土土垚的博客 &#x1f4a5; 所属专栏&#xff1a;C语言笔记 &#x1f4a5;欢迎大家&#x1f973;&#x1f973;点赞✨收藏&#x1f49…

【Node.js从基础到高级运用】二、搭建开发环境

Node.js入门&#xff1a;搭建开发环境 在上一篇文章中&#xff0c;我们介绍了Node.js的基础概念。现在&#xff0c;我们将进入一个更实际的阶段——搭建Node.js的开发环境。这是每个Node.js开发者旅程中的第一步。接下来&#xff0c;我们将详细讨论如何安装Node.js和npm&#…

将python编写的网站制作成docker镜像并上传到Github Packages上

文章目录 前言Docker安装docker注意事项 创建Dockerfile注意事项 构建 Docker 镜像运行 Docker 镜像 发布到Github Packages坑坑到位申请token的坑docker登录的坑给镜像添加标签的坑docker推送的坑 在Github Packages上查看总结 前言 还记得上一篇《借助ChatGPT使用Python搭建…

借助Aspose.html控件,在 Java 中将 URL 转换为 PDF

如果您正在寻找一种将实时 URL 中的网页另存为 PDF文档的方法&#xff0c;那么您来对地方了。在这篇博文中&#xff0c;我们将学习如何使用 Java 将 URL 转换为 PDF。从实时 URL转换HTML网页可以像任何其他文档一样保存所需的网页以供离线访问。将网页保存为 PDF 格式可以轻松突…

PandasAI—让AI做数据分析

安装 pip install pandasai !pip install --upgrade pandas pandasai 导入依赖项 import pandas as pdfrom pandasai import PandasAIfrom pandasai.llm.openai import OpenAI使用pandas创建一个数据框 df pd.DataFrame({"country": ["United States",…

MKS Type 631C 真空计说明详细内容查看图中目录

MKS Type 631C 真空计说明详细内容查看图中目录