图的遍历详解

目录

采用DFS遍历图

采用BFS遍历图

采用DFS遍历图

(1)邻接矩阵版

int n,G[maxn][maxn];
bool vis[maxn]={false};
void dfs(int u,int depth){vis[u]=true;for(int v=0;v<n;v++){if(vis[v]==false&&G[u][v]!=INF){dfs(v,depth+1);}}
}
void dfstrave(){for(int u=0;u<n;u++){if(vis[u]==false){dfs(u,1);}}
}

(2)邻接表版

vector<int> Adj[maxn];
int n;
bool vis[maxn]={false};
void dfs(int u,int depth){vis[u]=true;for(int i=0;i<Adj[u].size();i++){int v=Adj[u][i];if(vis[v]==false){dfs(v,depth+1);}}
}
void dfstrave(){for(int u=0;u<n;u++){if(vis[u]==false){dfs(u,1);}}
}

例题

 给出若干人之间的通话长度(视为无向边),这些通话将他们分为若干组。每个组的总边权 设为该组内的所有通话的长度之和,而每个人的点权设为该人参与的通话长度之和。现在给定一个阈值K,且只要一个组的总边权超过K,并满足成员人数超过2,则该数组视为犯罪团伙,而该组内点权最大的人视为头目,要求输出“犯罪团伙”的个数,并按头目姓名字典序从小到大的顺序输出每个“犯罪团伙”的头目姓名和成员人数。

思路

(1)首先需要解决的问题是姓名与编号的对应关系。方法有二:一是使用map<string,int>直接建立字符串与整型的映射关系;二是使用字符串hash的方法将字符串转换为整型。编号与姓名的对应关系则可以直接用string数组进行定义,或者使用map<int,string>也是可以的。

(2)根据题目中的要求,需要获得每个人的点权,即与之相关的通话记录的时长之和,而这显然可以在读入时就进行处理(假设A与B的通话时长为T,那么A与B的点权分别增加T)。事实上,该步是在求与某个点相连的边的边权之和。

(3)进行图的遍历。使用DFS遍历每个连通块,目的是获取每个连通块的头目(即连通块内点权最大得结点)、成员个数、总边权。

(4)通过步骤3可以获得连通块的总边权totalValue。如果totalValue大于给定的阈值K,且成员人数大于2,则说明该连通块是一个团伙,将该团伙的信息存储下来。

注:可以定义map<string,int>来建立团队头目的姓名与成员人数的映射关系。由于map中元素自动按键从小到大排序,因此自动满足了题目要求的“姓名字典序从小到大输出“的规定。

#include<iostream>
#include<string>
#include<map>
using namespace std;
const int maxn=2010;
const int INF=1000000000;
map<int,string> intToString;
map<string,int> stringToInt;
map<string,int> Gang;
int G[maxn][maxn]={0},weight[maxn]={0};
int n,k,numPerson=0;
bool vis[maxn]={false};
void dfs(int nowVisit,int& head,int& numMember,int& totalValue){numMember++;vis[nowVisit]=true;if(weight[nowVisit]>weight[head]){head=nowVisit;}for(int i=0;i<numPerson;i++){if(G[nowVisit][i]>0){totalValue+=G[nowVisit][i];G[nowVisit][i]=G[i][nowVisit]=0;if(vis[i]==false){dfs(i,head,numMember,totalValue);}}}
}
void dfstrave(){for(int i=0;i<numPerson;i++){if(vis[i]==false){int head=i,numMember=0,totalValue=0;dfs(i,head,numMember,totalValue);if(numMember>2&&totalValue>k){Gang[intToString[head]]=numMember;}}}
}
int change(string str){if(stringToInt.find(str)!=stringToInt.end()){return stringToInt[str];}else{stringToInt[str]=numPerson;intToString[numPerson]=str;return numPerson++;}
}
int main(){int w;string str1,str2;cin>>n>>k;for(int i=0;i<n;i++){cin>>str1>>str2>>w;int id1=change(str1);int id2=change(str2);weight[id1]+=w;weight[id2]+=w;G[id1][id2]+=w;G[id2][id1]+=w;}dfstrave();cout<<Gang.size()<<endl;map<string,int>::iterator it;for(it=Gang.begin();it!=Gang.end();it++){cout<<it->first<<" "<<it->second<<endl;}return 0;
}

采用BFS遍历图

(1)邻接矩阵版

int n,G[maxn][maxn];
bool inq[maxn]={false};
void bfs(int u){queue<int> q;q.push(u);inq[u]=true;while(!q.empty()){int u=q.front();q.pop();for(int v=0;v<n;v++){if(inq[v]==false&&G[u][v]!=INF){q.push(v);inq[v]=true;}}} 
}
void bfstrave(){for(int u=0;u<n;u++){if(inq[u]==false){bfs(u);}}
}

(2)邻接表版

vector<int> Adj[maxn];
int n;
bool inq[maxn]={false};
void bfs(int n){queue<int> q;q.push(u);inq[u]=true;while(!q.empty()){int u=q.front;q.pop();for(int i=0;i<Adj[u].size();i++){int v=Adj[u][i];if(inq[v]==false){q.push(v);inq[v]=true;}}}
}
void bfstrave(){for(int u=0;u<n;u++){if(inq[u]==false){bfs(u);}}
}

例题

在微博里,每个用户都可能被若干个其他用户关注。而当该用户发布一条信息时,他的关注者就可以看到这条信息并选择是否转发它,且转发的信息也可以被转发者的关注者再次转发,但同一用户最多只转发该信息一次(信息的最初发布者不会转发该信息)。现在给出N个用户的关注情况(即他们各自关注了哪些用户)以及一个转发层数上限L,并给出最初发布信息的用户编号,求在转发层数上线内信息最多会被多少用户转发。

思路

(1)首先考虑如何建图。由于题目给定的数据是用户关注的情况(而不是被关注的情况),因此如果用户X关注了用户Y,则需要建立由Y指向X的有向边,来表示Y发布的信息可以传递到X并被X转发。

(2)在建图完毕后,使用DFS或者BFS都可以得到需要的结果。如果使用DFS来遍历,只要控制遍历深度不超过题目给定的层数L即可。遍历过程中计数访问到的结点个数(细节处理会比较麻烦)。如果使用BFS来遍历,则需要把结点编号和层号建立成结构体,然后控制遍历层数不超过L

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1010;
struct node{int id;int layer;
};
vector<node> Adj[maxn];
bool inq[maxn]={false};
int bfs(int s,int l){int numForward=0;queue<node> q;node start;start.id=s;start.layer=0;q.push(start);inq[start.id]=true;while(!q.empty()){node topNode=q.front();q.pop();int u=topNode.id;for(int i=0;i<Adj[u].size();i++){node next=Adj[u][i];next.layer=topNode.layer+1;if(inq[next.id]==false&&next.layer<=l){q.push(next);inq[next.id]=true;numForward++;}}}return numForward;
}
int main(){node user;int n,l,numFollow,idFollow;scanf("%d%d",&n,&l);for(int i=1;i<=n;i++){user.id=i;scanf("%d",&numFollow);for(int j=0;j<numFollow;j++){scanf("%d",&idFollow);Adj[idFollow].push_back(user);}}int numQuery,s;scanf("%d",&numQuery);for(int i=0;i<numQuery;i++){memset(inq,false,sizeof(inq));scanf("%d",&s);int numForward=bfs(s,l);printf("%d\n",numForward);}return 0;
}

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

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

相关文章

算法笔记1-高精度模板(加减乘除)个人模板

目录 加法 减法 乘法 ​编辑 除法 加法 #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue>using namespace std;typedef pair<int,int> PII;const int N 1e5 10;int n; int a[N],…

ROS学习记录:C++节点发布自定义地图

前言 ROS栅格地图格式 在了解了ROS地图消息包的数据结构后(链接在上)&#xff0c;本文将编写一个节点&#xff0c;发布地图消息包&#xff0c;看看在RViz中显示是什么效果。 一、准备 1、为了简单起见&#xff0c;发布一个两行四列的地图 2、为了便于观测&#xff0c;只对地…

机器学习:如何在Python中实现决策树分类?

如何在Python中实现决策树分类&#xff1f; 在机器学习领域&#xff0c;决策树算法是一种常用且高效的分类与回归方法。它不仅易于理解和解释&#xff0c;还能处理数值型和分类型数据。本文将带你深入探索Python中的决策树算法&#xff0c;理解其基本原理&#xff0c;并通过代…

SmartEDA VS Multisim/Proteus:电子设计江湖,谁主沉浮?

在电子设计的江湖里&#xff0c;SmartEDA、Multisim和Proteus无疑是几大门派&#xff0c;各自拥有独特的武功秘籍和门派特色。今天&#xff0c;我们就来一场巅峰对决&#xff0c;看看这些电子设计软件究竟谁能笑傲江湖&#xff0c;成为电子设计界的霸主&#xff01; 一、门派起…

Linux:通过线程互斥同步实现基于BlockingQueue的生产消费者模型

一、总体调度&#xff1a;主函数Main.cc #include "BlockQueue.hpp" #include "Thread.hpp" #include <string> #include <vector> #include <functional> #include <unistd.h> #include <ctime>using namespace ThreadMod…

Seq2seq、编码器解码器神经网络

目录 一、Seq2seq 简介二、编码器三、解码器四、编码器-解码器的训练 遇到看不明白的地方&#xff0c;欢迎在评论中留言呐&#xff0c;一起讨论&#xff0c;一起进步&#xff01; 需掌握的前提知识&#xff1a; LSTM、词嵌入 本文参考&#xff1a;【官方双语】编码、解码神经网…

PasteCluster组件介绍(一款让你的.Net服务快速支持集群部署的中间件)

前言 PasteCluster是由.NET6.0编写的集群中间件&#xff0c;先已开源: PasteCluster.Gitee 在实际开发中&#xff0c;如果一个服务(比如api)是否支持集群部署&#xff0c;其实是由开发决定的&#xff01; 举个栗子 我们知道缓存&#xff0c;可以分几种方式&#xff0c;最简单的…

tkinter菜单栏

tkinter菜单栏 菜单栏效果代码 菜单栏 在 Tkinter 中&#xff0c;Menu 组件用于创建菜单栏、下拉菜单和上下文菜单&#xff0c;是构建图形用户界面&#xff08;GUI&#xff09;应用程序的常见需求。 效果 代码 import tkinter as tk from tkinter import messagebox# 创建主…

DAMA学习笔记(一)-数据管理

1.引言 数据管理(Data Management) 是为了 交付、 控制、 保护 并 提升 数据和信息资产的 价值 , 在其整个生命周期中制订 计划、 制度、 规程和实践 活动, 并 执行 和 监督 的过程。 数据管理专业人员(Data Management Professional) 是指 从事数据管理各方面的工作…

MySQL与PostgreSQL关键对比三(索引类型)

目录 索引类型 B-tree 索引 Hash 索引 Full-text 索引 GiST 索引 GIN 索引 BRIN 索引 索引创建示例 MySQL PostgreSQL 结论 以下SQL语句的执行如果需要开发工具支持&#xff0c;可以尝试使用SQLynx或Navicat来执行。 MySQL和PostgreSQL在索引方面有许多相似之处&am…

【C#线程设计】2:backgroundWorker

实现&#xff1a; &#xff08;1&#xff09;.控件&#xff1a;group Box&#xff0c;text Box&#xff0c;check Box&#xff0c;label&#xff0c;botton&#xff0c;richtextbox 控件拉取见&#xff1a;https://blog.csdn.net/m0_74749240/article/details/139409510?spm1…

mingw如何制作动态库附python调用

1.mingw和msvc g -fpic HelloWorld.cpp -shared -o test.dllg -L . -ltest .\test.cpp 注意-L后面的.挨不挨着都行&#xff0c;-l不需要-ltest.dll&#xff0c;只需要-ltest 2.dll.cpp extern "C" {__declspec(dllexport) int __stdcall add(int a, int b) {return…

吴恩达2022机器学习专项课程C2W3:2.25 理解方差和偏差(诊断方差偏差正则化偏差方案)

目录 引言名词替代影响模型偏差和方差的因素1.多项式阶数2.正则化参数 判断是否有高偏差或高方差1.方法一&#xff1a;建立性能基准水平2.方法二&#xff1a;建立学习曲线 总结 引言 机器学习系统开发的典型流程是从一个想法开始&#xff0c;然后训练模型。初次训练的结果通常…

C语言最终讲:预处理详解

C语言最终讲&#xff1a;预处理详解 1.预定义符号2.#define定义常量3.#define定义宏4.带有副作用的宏参数5.宏替换的规则6.宏和函数的对比6.1宏的优势6.1.1\符号 6.2宏的劣势 7.#和##7.1#运算符7.2##运算符 8.命名约定9.#undef10.命令行定义11.条件编译12.头文件的包含12.1本地…

13. UDP协议与RTP协议

UDP协议 UDP协议比较简单&#xff1a; UDP的长度是固定的&#xff0c;用总长度-UDP长度就是数据长度。 UDP是不保证他的有序性和可靠性的。对于音频和视频是这样是比较好的&#xff0c;因为这段丢了&#xff0c;我们可以从下一段在开始解码。 RTP RTP 协议概述 RTP&#x…

【MySQL】(基础篇六) —— 过滤数据

过滤数据 本文将讲授如何使用SELECT语句的WHERE子句指定搜索条件。 WHERE子句 数据库表一般包含大量的数据&#xff0c;很少需要检索表中所有行。通常只会根据特定操作或需要提取表数据的子集。只检索所需数据需要指定搜索条件&#xff08;search criteria&#xff09;&…

独孤思维:做副业,万物皆可成为素材

01 分享一个独孤日更的素材来源。 很多小伙伴&#xff0c;刚开始写自媒体&#xff0c;都喜欢一本正经的阅读书籍&#xff0c;文章。 把素材来源&#xff0c;灵感来源&#xff0c;全部押注在这个地方。 其实万物皆可成为素材。 比如昨天早上&#xff0c;独孤参加公司的会议…

代码随想录算法训练营第36期DAY56

DAY56 套磁很顺利&#xff0c;发现又有书读了&#xff01; 300最长递增子序列 朴素法&#xff0c;这个好想&#xff0c;但是不对&#xff0c;比如 0 1 0 3 2 3 我的算法会找出0 1 3作为答案&#xff0c;而不是0 1 2 3 可以看出&#xff0c;后面的状态依赖于前面的状态&am…

zero shot,few shot以及无监督学习之间的关系是什么

Zero-shot learning、few-shot learning和无监督学习都是机器学习中的方法&#xff0c;它们共同的特点是在有限或没有标签数据的情况下进行学习。下面是这三种方法之间的关系和区别&#xff1a; Zero-shot Learning (零样本学习)&#xff1a; 零样本学习是在模型训练过程中完全…

中介子方程十

X$XFX$XEXyXαXiX$XαXiXrXkXtXyX$XpX$XyXtXkXrXiXαX$XiXαXyXEX$XFX$XEXyXαXiX$XαXiXrXkXtXyX$XpX$XyXtXkXrXiXαX$XiXαXyXEX$XαXηXtXαX$XWXyX$XyXWX$XpXαXqXηX$XeXαXhX$XdX$XpX$XdX$XyXeXαX$XEXyXαXiX$XαXiXrXkXtXyX$XpX$XyXtXkXrXiXαX$XiXαXyXEX$XαXeXyX$Xd…