当前位置: 首页 > news >正文

【PTA数据结构 | C语言版】双连通分量

本专栏持续输出数据结构题目集,欢迎订阅。

文章目录

    • 题目
    • 代码

题目

本题请你编写程序,输出给定无向连通图中的割点和割边。

输入格式:
输入首先在第一行给出图中最大顶点数量,即正整数 kMaxVertex(≤20)。
第二行给出两个正整数,依次为当前要创建的图的顶点数 n 和边数 m(保证顶点数至少为 2 且不超过最大顶点数量)。
第三行给出 n 个小写英文字母,其间以 1 个空格分隔,顺序对应每个顶点的信息。
随后 m 行,每行给出一条无向边的两个端点的编号。顶点编号从 0 开始,编号间以 1 个空格分隔。
题目保证没有边被重复给出,并且图一定是连通的。

输出格式:
首先在一行中输出所有割点的字母信息,中间不要空格。如果没有割点则输出一个空行。
随后每行按格式 (v1, v2) 输出一条割边,其中 v1 和 v2 为割边两端点的字母信息。如果没有割边则不要输出任何信息。

输入样例:
20
10 11
a b c d e f g h i j
0 1
1 2
1 3
2 4
3 4
3 5
5 6
5 7
6 7
7 8
7 9

输出样例:
bdfh
(b, a)
(d, f)
(h, i)
(h, j)

注意:割点和割边的输出顺序是不唯一的,以任何顺序输出都可以,有特殊裁判程序判断输出的正确性。例如下列输出也是正确的。

hbdf
(d, f)
(h, i)
(a, b)
(h, j)

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_VERTEX 20typedef struct Node {int vertex;struct Node* next;
} Node;typedef struct {Node* adj[MAX_VERTEX];int n;char vertices[MAX_VERTEX];
} Graph;// 全局变量
int time;
int disc[MAX_VERTEX];    // 发现时间
int low[MAX_VERTEX];     // 最早可达祖先的发现时间
int parent[MAX_VERTEX];  // 父节点
int ap[MAX_VERTEX];      // 标记割点
int bridges[MAX_VERTEX][MAX_VERTEX]; // 标记割边// 函数声明
void initGraph(Graph* g, int n);
void addEdge(Graph* g, int src, int dest);
void findAPAndBridges(Graph* g);
void APUtil(Graph* g, int u);
void printResults(Graph* g);int main() {int kMaxVertex;(void)scanf("%d", &kMaxVertex);int n, m;(void)scanf("%d %d", &n, &m);Graph g;initGraph(&g, n);// 读取顶点信息for (int i = 0; i < n; i++) {(void)scanf(" %c", &g.vertices[i]);}// 读取边信息for (int i = 0; i < m; i++) {int src, dest;(void)scanf("%d %d", &src, &dest);addEdge(&g, src, dest);}// 初始化time = 0;for (int i = 0; i < n; i++) {disc[i] = -1;low[i] = -1;parent[i] = -1;ap[i] = 0;for (int j = 0; j < n; j++) {bridges[i][j] = 0;}}// 查找割点和割边findAPAndBridges(&g);// 输出结果printResults(&g);return 0;
}// 初始化图
void initGraph(Graph* g, int n) {g->n = n;for (int i = 0; i < n; i++) {g->adj[i] = NULL;}
}// 添加无向边
void addEdge(Graph* g, int src, int dest) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->vertex = dest;newNode->next = g->adj[src];g->adj[src] = newNode;newNode = (Node*)malloc(sizeof(Node));newNode->vertex = src;newNode->next = g->adj[dest];g->adj[dest] = newNode;
}// 查找割点和割边
void findAPAndBridges(Graph* g) {// 对每个未访问的顶点调用APUtilfor (int i = 0; i < g->n; i++) {if (disc[i] == -1) {APUtil(g, i);}}
}// Tarjan算法核心函数
void APUtil(Graph* g, int u) {int children = 0;disc[u] = low[u] = ++time;Node* temp = g->adj[u];while (temp != NULL) {int v = temp->vertex;if (disc[v] == -1) {children++;parent[v] = u;APUtil(g, v);// 更新low值low[u] = (low[u] < low[v]) ? low[u] : low[v];// 检查是否为割点if (parent[u] == -1 && children > 1) {ap[u] = 1;}if (parent[u] != -1 && low[v] >= disc[u]) {ap[u] = 1;}// 检查是否为割边if (low[v] > disc[u]) {bridges[u][v] = bridges[v][u] = 1;}} else if (v != parent[u]) {// 更新low值为发现时间较小值low[u] = (low[u] < disc[v]) ? low[u] : disc[v];}temp = temp->next;}
}// 输出结果
void printResults(Graph* g) {// 输出割点for (int i = 0; i < g->n; i++) {  // 移除未使用的hasAP变量if (ap[i]) {printf("%c", g->vertices[i]);  // 使用->访问指针成员}}printf("\n");// 输出割边for (int i = 0; i < g->n; i++) {for (int j = i + 1; j < g->n; j++) {if (bridges[i][j]) {// 使用->访问指针成员printf("(%c, %c)\n", g->vertices[i], g->vertices[j]);}}}
}
http://www.lryc.cn/news/595187.html

相关文章:

  • Spring Boot自动装配原理深度解析:从核心注解到实现机制
  • AWS IoT Core CloudWatch监控完整指南
  • AWS Certified Cloud Practitioner 认证考试 测试题与解析
  • HCL 三层知识总结
  • PyTorch 实现 CIFAR-10 图像分类:从数据预处理到模型训练与评估
  • RAG实战指南 Day 20:大规模向量索引优化技术
  • 轮状太空城的科学依据浅谈
  • Linux的目录
  • 在github上搭建自己主页
  • GLog编译提示fatal error LNK1112: 模块计算机类型“x64”与目标计算机类型“X86”冲突问题的解决
  • 《探索Go语言:云时代的编程新宠》
  • Electron 主进程与渲染进程之间交互方式
  • 文娱投资的逆势突破:博派资本的文化旅游综合体战略
  • rancher上使用rke在华为云多网卡的服务器上安装k8s集群问题处理了
  • 安全告警研判流程
  • OpenGL鼠标控制沿着指定轴旋转
  • STM32 开发的鼠标:技术详解与实现指南
  • 数据结构堆的实现(C语言)
  • Selenium 处理表单、弹窗与文件上传:从基础到实战
  • Ubuntu 22.04 安装 Jdk 8和 Tomcat (安装包形式)
  • Ubuntu 22 集群部署 Apache Doris 3.0.3 笔记
  • 前端图像视频实时检测
  • GitHub+Git新手使用说明
  • Flutter中 Provider 的基础用法超详细讲解(一)
  • 数据库和数据仓库的区别
  • [Python]函数调用链中局部变量的内存影响:通过memory_profiler分析
  • 全新开发范式:uni-app X助力全平台原生应用
  • Type-C接口台式显示器:LDR6021引领新潮流
  • JAVA+AI教程-第三天
  • 将 RustFS 用作 GitLab 对象存储后端