PAT甲级 图的遍历 相关题_C++题解
图的遍历
PAT (Advanced Level) Practice 图的遍历 相关题
目录
- 《算法笔记》重点摘要
- 1021 Deepest Root (25)
- 1076 Forwards on Weibo (30)
《算法笔记》 10.3 图的遍历 重点摘要
1. 定义
- 边 两端可以是 相同 的顶点
- 可以把 无向图 当作所有 边 都由 正向 和 负向 两条 有向边 组成
- 顶点的度:与该顶点相连的边的条数
- 顶点和边量化的属性分别成为点权和边权
2. 存储
2.1 邻接矩阵
- G[i][j] 存放边权,不存在的边设边权为0、-1 或 一个很大的数
- 邻接矩阵只适用于顶点数目不太大(一般不超过 1000)的题目
2.2 邻接表
- 若只存放每条边的终点编号,vector 元素类型定义为 int 即可
vector<int> Adj[N];
Adj[u].push_back(v);
- 若同时存放终点编号和边权,可建立结构体,vector 元素类型定义为结构体
struct Node{
int v;
int weight;
};
vector<Node> Adj[N];
Adj[u].push_back({v,weight});
3. DFS
若已知给定图为连通图,则只需一次 DFS 即可完成遍历
const int MAXV = 1000;
const INF = 1000000000;
3.1 邻接矩阵
int n, G[MAXV][MAXV];
bool vis[MAXV] = {false};
void DFS(int u, int depth){
vis[u] = true;
// 若需要对 u 进行一些操作,在这里进行
for (int v = 0; v < n; v++)
if (!vis[v] && G[u][v] != INF)
DFS(v, depth + 1);
}
void DFSTrave(){
for (int u = 0; u < n; u++)
if (!vis[u])
DFS(u, 1);
}
3.2 邻接表
vector<int> Adj[MAXV];
int n;
bool vis[MAXV] = {false};
void DFS(int u, int depth){
vis[u] = true;
// 若需要对 u 进行一些操作,在这里进行
for(int i = 0; i < Adj[u].size(); i++){
int v = Adj[u][i];
if (!vis[v])
DFS(v, depth + 1);
}
}
void DFSTrave(){
for (int u = 0; u < n; u++)
if (!vis[u])
DFS(u,1);
}
4. BFS
4.1 邻接矩阵
int n, G[MAXV][MAXV];
bool inq[MAXV] = {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] && G[u][v] != INF){
q.push(v);
inq[v] = true;
}
}
}
}
void BFSTrave(){
for (int u = 0; u < n; u++)
if (!inq[u])
BFS(u);
}
4.2 邻接表
vector<int> Adj[MAXN];
int n;
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 i = 0; i < Adj[u].size(); i++){
int v = Adj[u][i];
if (!inq[v]){
q.push(v);
inq[v] = true;
}
}
}
}
void BFSTrave(){
for (int u = 0; u < n; u++)
if (!inq[u])
BFS(u);
}
4.3 输出结点层号(邻接表)
struct Node{
int v;
int level;
};
vector<Node> Adj[N];
void BFS(int s){
queue<Node> q;
Node start = {s,0};
q.push(start);
inq[start.v] = true;
while(!q.empty()){
Node now = q.front();
q.pop();
int u = now.v;
for (int i = 0; i < Adj[u].size(); i++){
Node next = Adj[u][i];
next.level = now.level + 1;
if (!inq[next.v]){
q.push(next);
inq[next.v] = true;
}
}
}
}
1021 Deepest Root (25)
题目思路
- 边为双向,邻接表法注意两个方向都要存储
- 先按正常 DFS 遍历一遍,记录连通分量个数
- 若不为树(分量个数 > 1),直接按要求输出分量个数即可
- 若为树(分量个数 = 1),分别以每个结点为根结点进行 DFS,记录这样遍历树的深度,与最大深度比较
- 相等则将此根压入根集合中
- 若大于最大深度,说明找到了更大深度,将之前的根集合清空,压入新发现的根结点
#include<iostream>
#include<vector>
#include<set>
using namespace std;
set<int> roots;
vector<int> Adj[10001];
int n, components = 0, depth = 0, maxdepth = 0;
bool vis[10001] = {false};
void DFS(int root, int level){
vis[root] = true;
if (level > depth) depth = level;
for (int i = 0; i < Adj[root].size(); i++)
if (!vis[Adj[root][i]])
DFS(Adj[root][i], level+1);
}
void DFSTrave(){
for (int i = 1; i < n + 1; i++){
if (!vis[i]){
DFS(i, 0);
components++;
}
}
if (components == 1){
for (int i = 1; i < n + 1; i++){
fill(vis, vis+10001, false);
depth = 0;
DFS(i,0);
if (depth == maxdepth) roots.insert(i);
else if (depth > maxdepth){
maxdepth = depth;
roots.clear();
roots.insert(i);
}
}
}
}
int main()
{
int u, v;
scanf("%d", &n);
for (int i = 1; i < n; i++){
scanf("%d%d", &u, &v);
Adj[u].push_back(v);
Adj[v].push_back(u);
}
DFSTrave();
if (components > 1) printf("Error: %d components\n", components);
else for (auto it: roots) printf("%d\n",it);
return 0;
}
1076 Forwards on Weibo (30)
题目思路:带层数的广度优先
- 用 Node 结构体同时保存 id 和 level
- 用 inq 记录结点是否入队过,入队过不能重复入队(重复转发消息)
- 记录结点层数,若超过要求的最高层数也不可再入队
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct Node{
int id, level;
};
int maxlevel, numforward;
vector<Node> Adj[1001];
void BFS(int start){
bool inq[1001] = {false};
queue<Node> q;
q.push({start,0});
inq[start] = true;
while (!q.empty()){
Node now = q.front();
q.pop();
for (int i = 0; i < Adj[now.id].size(); i++){
Node next = Adj[now.id][i];
next.level = now.level + 1;
if (!inq[next.id] && next.level <= maxlevel){
inq[next.id] = true;
q.push(next);
numforward++;
}
}
}
}
int main()
{
int n, m, followed, k, query;
scanf("%d%d", &n, &maxlevel);
for (int i = 1; i < n + 1; i++){
scanf("%d", &m);
for (int j = 0; j < m; j++){
scanf("%d", &followed);
Adj[followed].push_back({i,0});
}
}
scanf("%d", &k);
for (int i = 0; i < k; i++){
scanf("%d", &query);
numforward = 0;
BFS(query);
printf("%d\n", numforward);
}
return 0;
}
PAT甲级 图的遍历 相关题_C++题解的更多相关文章
- PAT甲级 并查集 相关题_C++题解
并查集 PAT (Advanced Level) Practice 并查集 相关题 <算法笔记> 重点摘要 1034 Head of a Gang (30) 1107 Social Clu ...
- PAT甲级 Dijkstra 相关题_C++题解
Dijkstra PAT (Advanced Level) Practice Dijkstra 相关题 目录 <算法笔记>重点摘要 1003 Emergency (25) <算法笔记 ...
- PAT甲级 二叉树 相关题_C++题解
二叉树 PAT (Advanced Level) Practice 二叉树 相关题 目录 <算法笔记> 重点摘要 1020 Tree Traversals (25) 1086 Tree T ...
- PAT甲级 二叉查找树 相关题_C++题解
二叉查找树 PAT (Advanced Level) Practice 二叉查找树 相关题 目录 <算法笔记> 重点摘要 1099 Build A Binary Search Tree ( ...
- PAT甲级 图 相关题_C++题解
图 PAT (Advanced Level) Practice 用到图的存储方式,但没有用到图的算法的题目 目录 1122 Hamiltonian Cycle (25) 1126 Eulerian P ...
- PAT甲级 树 相关题_C++题解
树 目录 <算法笔记>重点摘要 1004 Counting Leaves (30) 1053 Path of Equal Weight (30) 1079 Total Sales of S ...
- PAT甲级 堆 相关题_C++题解
堆 目录 <算法笔记>重点摘要 1147 Heaps (30) 1155 Heap Paths (30) <算法笔记> 9.7 堆 重点摘要 1. 定义 堆是完全二叉树,树中每 ...
- PAT甲级 散列题_C++题解
散列 PAT (Advanced Level) Practice 散列题 目录 <算法笔记> 重点摘要 1002 A+B for Polynomials (25) 1009 Product ...
- PAT甲级 排序题_C++题解
排序题 PAT (Advanced Level) Practice 排序题 目录 <算法笔记> 6.9.6 sort()用法 <算法笔记> 4.1 排序题步骤 1012 The ...
随机推荐
- zabbix (一) 初识
1.什么是zabbix? Zabbix由Alexei Vladishev创建,目前由Zabbix SIA积极开发和支持. Zabbix是一种企业级开源分布式监控解决方案. Zabbix是监控底层存储( ...
- shell 脚本同时对远程多台机器执行命令
脚本1:需要机器之间免密 ssh-copy-id [-i [identity_file]] [user@]machine #!/bin/bash # ------------------------- ...
- 针对于linux初学者的学习(摘自网络端)
一. 选择适合自己的Linux发行版谈到linux的发行版本,太多了,可能谁也不能给出一个准确的数字,但是有一点是可以肯定的,linux正在变得越来越流行, 面对这么多的Linux 发行版,打算从其他 ...
- 2.linux的增删改查
一.增删改查 1.建立文件和目录 mkdir /tmp/xueying 2.cd 进入的路径 绝对路径:以根目录为其实目录的路径 ...
- 标准6轴机器人正反解(1)-坐标系和MDH参数表
刚来新公司不久,部门给安排了新人作业,我被分到的任务是求标准6轴机器人的正反解,以及利用就近原则选择最优解.从今天开始,逐步将这部分内容总结出来: 本文以及后续文章均使用改进DH法: 连杆坐标系: 坐 ...
- 2018-2019-2 (内附jdk与webgoat完整安装教程)《网络对抗技术》Exp9 Web安全基础 Week13 20165233
Exp9 Web安全基础 目录 一.基础问题 二.实验步骤 实验前准备:jdk与webgoat的安装 实验点一:SQL 命令注入(Command Injection) 数字型注入(Numeric SQ ...
- node.js 简易聊天室
效果图 首先开启server.js 打开服务器端,然后打开client.js,注册用户.打开一个注册一个用户,打开三个,注册三个用户. 接下来,小王发布一个广播消息,小李和小刘都收到了此消息. 接下来 ...
- jQuery之编写插件
一.学习插件编写背景 作为一名前端人员,应该注重前端复用性及组件化,更应该考虑前端的性能优化,做到代码简洁有序,不冗余.特别是在大型团队中,如果一个团队中存在多个功能相似的组件,举个栗子,拿分页组件举 ...
- Windows 自动定时执行任务的方法
windows 自动定时执行任务的几种实现方法 Task Schedul Windows自动定时执行任务,常见的方法有三种: Windows 任务计划程序 Windows Service SQL ...
- lua日期处理函数
function day_step(old_day,step) local y,m,d if("0" ~= string.sub(old_day,6,6)) then ...