图论入门题题解

这篇具有很好参考价值的文章主要介绍了图论入门题题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

图论入门题题解,刷题,图论

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

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

          所属专栏:刷题_脑子不好的小菜鸟的博客-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;
}

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

图论入门题题解,刷题,图论文章来源地址https://www.toymoban.com/news/detail-840707.html

到了这里,关于图论入门题题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • B3610 [图论与代数结构 801] 无向图的块 题解

    2023 2023 2023 ,再见。 2024 2024 2024 ,你好! 其实就是统计点双连通分量的个数。需要注意的是,孤立点在这里不被看作块。本文使用 tarjan 算法来解决这道题。 概念明晰 时间戳:这里记为 d f n i dfn_i df n i ​ ,表示第一次深度优先搜索到节点 i i i 的时间。时间 t i m e ∈ N + t

    2024年02月03日
    浏览(41)
  • 刷题笔记26——图论二分图判定

    世界上的事情,最忌讳的就是个十全十美,你看那天上的月亮,一旦圆满了,马上就要亏厌;树上的果子,一旦熟透了,马上就要坠落。凡事总要稍留欠缺,才能持恒。 ——莫言 visited数组是在如果有环的情况下,防止在图中一直绕圈设置的,类似于剪枝操作,走过了就没必要再走一遍

    2024年02月07日
    浏览(40)
  • 刷题笔记25——图论课程表

    为了最终理解你所不理解的,你必须经历一条愚昧无知的道路。为了占有你从未占有的东西,你必须经历被剥夺的道路。为了达到你现在所不在的名位,你必须经历那条你不在其中的道路。——艾略特 非常奇妙,我最初的错误是如下,在找到目标节点后直接加入到res中,但是

    2024年02月07日
    浏览(38)
  • 【图论刷题-6】力扣 797. 所有可能的路径

    机器人的运动范围 矩阵中的路径 图像渲染 水位上升的泳池中游泳 寻找图中是否存在路径 所有可能的路径 力扣地址:https://leetcode.cn/problems/all-paths-from-source-to-target/ 这是一道比较典型的深度优先遍历、广度优先遍历案例,强烈推荐初学者完成这道题并且常常回来看看(也欢

    2024年02月06日
    浏览(42)
  • 【刷题】图论——最小生成树:Prim、Kruskal【模板】

    假设有n个点m条边。 Prim适用于邻接矩阵存的稠密图,时间复杂度是 O ( n 2 ) O(n^2) O ( n 2 ) ,可用堆优化成 O ( n l o g n ) O(nlogn) O ( n l o g n ) 。 Kruskal适用于稀疏图,n个点m条边,时间复杂度是 m l o g ( m ) mlog(m) m l o g ( m ) 。 Prim:遍历n次,每次选择 连通块和外面的点 到连通块距离

    2024年04月13日
    浏览(44)
  • 【刷题1】LeetCode 131. 分割回文串 java题解

    2024: 刚开始做leetcode hot100,查阅自己以前写的题解专栏,发现没有这一题,于是加上。可能leetcode100更新了吧。我看现在leetcode100官网的题目已经是分好类的了,以前我的题解帖子是自己手动分类整理的。

    2024年02月19日
    浏览(42)
  • 【离散数学】——期末刷题题库(图论应用题)

    🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL:数据结构_IT闫的博客-CSDN博客 🐠数据结构:​​​​​​数据结构_IT闫的博客-CSDN博客 💎C++:C++_IT闫的博客-CSDN博

    2024年02月04日
    浏览(38)
  • leetcode&lintcode分类刷题:图论(三、多源最小距离问题)

    1、本次总结的题目通常是多个源头节点分别求解到达目标节点的最小距离,目标节点可能为多个,也可能为一个;要采用 广度优先搜索 的方法,但先提前入队的不是源头节点了,而是目标节点,由目标节点为基准一圈一圈的更新能够达到的“新目标”位置,每一圈更新能够

    2024年02月07日
    浏览(39)
  • 【寸铁的刷题笔记】树、回溯、图论、bfs、dfs(四)

    大家好 我是寸铁👊 金三银四 , 图论基础 、 回溯 结合 bfs 、 dfs 是必考的知识点✨ 快跟着寸铁刷起来!面试顺利上岸👋 喜欢的小伙伴可以点点关注 💝 🌞详见如下专栏🌞 🍀🍀🍀 寸铁的刷题笔记 🍀🍀🍀 考点 dfs、回溯 代码 考点 dfs、回溯 代码 考点 bfs、宽度搜索、哈

    2024年03月11日
    浏览(53)
  • Leetcode刷题笔记题解(C++):203. 移除链表元素

    思路:不同的情况出现了,就是第一个节点要是为等于val的节点,可以新建一个节点,并next指向head,这样就可以遍历新的链表来删除节点

    2024年02月22日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包