寻找关节点(重连通分量)

 

#include <stdio.h>
#include <string.h>
#define OK 1
#define INFINITY 32767
#define MAX_VERTEX_NUM 30
#define MAXINFOLEN 30
#define ERROR 0
#define OVERFLOW -1
#define MAXVERTEXLEN 30
#define FALSE 0
#define TRUE 1
typedef int Status;
typedef enum { DG, DN, UDG, UDN }GraphKind;
typedef int VRType;
typedef int InfoType;
typedef char* VertexType;
//邻接表存储图结构
typedef struct ArcNode
{
	struct ArcNode* nextarc;
	InfoType* info;
	int adjvex;
}ArcNode;
typedef struct VNode
{
	VertexType data;
	ArcNode* firstnode;
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct
{
	AdjList vertices;
	int vexnum, arcnum;
	GraphKind kind;
}ALGraph;
void CreatGraph_AL(ALGraph* G)
{
	printf("请输入邻接表存储图的种类,且只能存储有向图(0)与无向图(2)\n");
	scanf("%d", &(G->kind));
	int info;
	printf("请依次输入图的节点数,弧数,是否需要弧的信息\n");
	scanf("%d%d%d", &(G->vexnum), &(G->arcnum), &info);
	getchar();
	for (int i = 0; i < G->vexnum; i++)
	{
		printf("请输入图的第%d个节点的描述\n", i + 1);
		G->vertices[i].data = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
		if (!G->vertices[i].data) exit(OVERFLOW);
		gets(G->vertices[i].data);
		G->vertices[i].firstnode = NULL;
	}
	char* ch;
	ch = (char*)malloc(sizeof(char) * MAXVERTEXLEN);
	if (!ch) exit(OVERFLOW);
	if (G->kind == DG)
	{
		int tail, head;
		for (int i = 0; i < G->arcnum; i++)
		{
			printf("请输入第%d个节点关系\n", i + 1);
			printf("请输入弧尾描述信息\n");
			gets(ch);
			for (int j = 0; j < G->vexnum; j++)
			{
				if (strcmp(G->vertices[j].data, ch) == 0)
				{
					tail = j;
					break;
				}
			}
			printf("请输入弧头描述信息\n");
			gets(ch);
			for (int j = 0; j < G->vexnum; j++)
			{
				if (strcmp(G->vertices[j].data, ch) == 0)
				{
					head = j;
					break;
				}
			}
			ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));
			if (!p) exit(OVERFLOW);
			p->adjvex = head;
			ArcNode* s = G->vertices[tail].firstnode;
			if (!s)
			{
				p->nextarc = G->vertices[tail].firstnode;
				G->vertices[tail].firstnode = p;
			}
			else
			{
				while (s->nextarc)
					s = s->nextarc;
				p->nextarc = s->nextarc;
				s->nextarc = p;
			}
			if (info)
			{
				printf("请输入弧的描述信息\n");
				p->info = (int*)malloc(sizeof(int));
				if (!p->info) exit(OVERFLOW);
				scanf("%d", p->info);
				getchar();
			}
		}
	}
	else
	{
		int vex1, vex2;
		for (int i = 0; i < G->arcnum; i++)
		{
			printf("请输入第%d个节点关系\n", i + 1);
			printf("请输入第一个相关节点描述信息\n");
			gets(ch);
			for (int j = 0; j < G->vexnum; j++)
			{
				if (strcmp(G->vertices[j].data, ch) == 0)
				{
					vex1 = j;
					break;
				}
			}
			printf("请输入第二个相关节点描述信息\n");
			gets(ch);
			for (int j = 0; j < G->vexnum; j++)
			{
				if (strcmp(G->vertices[j].data, ch) == 0)
				{
					vex2 = j;
					break;
				}
			}
			ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));
			if (!p) exit(OVERFLOW);
			p->adjvex = vex1;
			ArcNode* s = G->vertices[vex2].firstnode;
			if (!s)
			{
				p->nextarc = G->vertices[vex2].firstnode;
				G->vertices[vex2].firstnode = p;
			}
			else
			{
				while (s->nextarc)
					s = s->nextarc;
				p->nextarc = s->nextarc;
				s->nextarc = p;
			}
			if (info)
			{
				printf("请输入弧的描述信息\n");
				p->info = (int*)malloc(sizeof(int));
				if (!p->info) exit(OVERFLOW);
				scanf("%d", p->info);
				getchar();
			}
			ArcNode* q = (ArcNode*)malloc(sizeof(ArcNode));
			if (!q) exit(OVERFLOW);
			q->adjvex = vex2;
			s = G->vertices[vex1].firstnode;
			if (!s)
			{
				q->nextarc = G->vertices[vex1].firstnode;
				G->vertices[vex1].firstnode = q;
			}
			else
			{
				while (s->nextarc)
					s = s->nextarc;
				q->nextarc = s->nextarc;
				s->nextarc = q;
			}
			if (info)
			{
				printf("请输入弧的描述信息\n");
				p->info = (int*)malloc(sizeof(int) * MAXINFOLEN);
				if (!p->info) exit(OVERFLOW);
				scanf("%d", p->info);
				getchar();
			}
		}
	}
}
//寻找关节点与重连通分量
int visited[MAX_VERTEX_NUM];
int low[MAX_VERTEX_NUM];
int count = 1;
void DFS(ALGraph G, int i)
{
	visited[i] = ++count;
	int min = visited[i];
	ArcNode* p = G.vertices[i].firstnode;
	while (p)
	{
		int j = p->adjvex;
		if (visited[j] == 0)
		{
			DFS(G, j);
			if (low[j] < min)
				min = low[j];
			if (low[j] >= visited[i])
				printf("%s是关节点,删去%s,%s会成为独立的图\n", G.vertices[i].data, G.vertices[i].data, G.vertices[j].data);
		}
		else
			if (visited[j] < min)
				min = visited[j];
		p = p->nextarc;
	}
	low[i] = min;
}
int main()
{
	ALGraph G;
	CreatGraph_AL(&G);
	visited[0] = 1;
	for (int i = 1; i < G.vexnum; i++)
		visited[i] = 0;
	ArcNode* p = G.vertices[0].firstnode;
	int k = p->adjvex;
	DFS(G, k);
	if (count < G.vexnum)
	{
		printf("%s是关节点\n", G.vertices[0].data);
		while (p->nextarc)
		{
			p = p->nextarc;
			k = p->adjvex;
			if (visited[k] == 0)
				DFS(G, k);
		}
	}
	return 0;
}

原图:

 

 输入:(P177图7.19)

2
13 17 0
A
B
C
D
E
F
G
H
I
J
K
L
M
A
B
A
C
A
L
A
F
B
D
D
E
B
G
B
H
B
M
G
H
G
I
G
K
H
K
J
L
J
M
L
M
B
C

结果:

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值