PTA는 연결된 집합을 나열합니다 --- 대칭 배열의 보존

아이디어

이 질문은 그래프의 저장 및 순회 (BFS, DFS) 작업을 테스트하는 것입니다.

그래프는 인접 행렬과 인접 목록을 저장하며,이 질문에서는 인접 행렬을 사용하며 인접 행렬을 저장하는 두 가지 방법도 있습니다.

  1. 2 차원 배열을 정의하여 각 포인트의 모든 간선을 저장합니다. 무 방향 그래프의 경우 각 간선은 두 간선을 저장해야합니다.
  2. 1 차원 배열을 정의합니다. 무 방향 그래프의 경우 방법 1 (각 모서리에 대해 한 번 저장 됨)에서 2 차원 배열의 하위 삼각 행렬 만 첫 번째 방법에 비해 많은 공간을 절약 할 수 있습니다.
  3. 두 번째 방법은이 1 차원 배열에서 두 노드 사이의 가장자리 아래 첨자는 다음과 같습니다.여기에 사진 설명 삽입

에러 코드

void DFS(int* G, int* visit, int N, int V) {
    
    
	visit[V] = 1;
	printf("%d ", V);
	//错误地方
	for (int i = V; i < N; i++) {
    
     //遍历每个临界点 对某个点的临界点来说,要按下三角矩阵遍历列
		if (G[i * (i + 1) / 2 + V] == 1 && visit[i] != 1) {
    
    
			DFS(G, visit, N, i);
		}
	}
}

void BFS(int* G, int* visit, int N, int V) {
    
    
	visit[V] = 1;
	printf("%d ", V);
	Enquee(V);
	while(!IsEmpty()) {
    
    
		V = Dequee();	//以下遍历V的临接点
		//错误地方
		for (int i = V; i < N; i++) {
    
     //遍历每个临接点 对某个点的临接点来说,要按下三角矩阵遍历列
			if (G[i * (i + 1) / 2 + V] == 1 && visit[i] != 1) {
    
    
				visit[i] = 1;
				printf("%d ", i);
				Enquee(i);
			}
		}
	}
}


해석 오류

매우 이상합니다. 오류 코드가 여전히 전송되는 이유는 무엇입니까?
내 그래프의 저장 방법은 에러 코드에서 공간을 절약하는 두 번째 방법을 사용하기 때문인데 두 번째 방법을 사용하면 어떨까요? ? ?
사례를 살펴 보겠습니다.

10	7
1	4
1	3
1	5
4	2
6	7
6	9
7	8

이 경우 문제는 가장자리 4 2입니다.이 경우의 그림을 그리면 (너무 못 생겼고 그리지 않았습니다) 노드 1과 노드 4 사이에 가장자리가 있고 노드 4와 노드 2에는 가장자리가 있습니다.

  • 다시 말해:
    트래버스 할 때 먼저 노드 1로 트래버스 한 다음 노드 4로 트래버스하고 마지막으로 노드 2로 트래버스해야합니다.
  • 하나두 번째 저장 방법에서는 노드의 인접 행렬을 탐색 할 때 하위 삼각 행렬에 해당하는 열을 탐색하여 1의 값을 찾습니다 (예 : v0 대신 v3에서 시작하여 v3의 인접 지점 탐색). . 따라서 노드 4 의 인접 노드를 탐색 할 때 노드 4에서 시작하여 노드 2를 찾지 못했습니다.

올바른 코드

그래프를 저장하는 데 사용되는 첫 번째 방법은 2 차원 행렬로 저장하여 노드의 인접 행렬을 찾을 때 해당 열이 2 차원이기 때문에 단순히 순회 할 수 있으므로 각 순회는 v0 시작

노트

2 차원 배열을 사용하여 매개 변수를 전달할 때 형식 매개 변수는 배열 포인터를 사용합니다. int (* G) [10]

#include <stdio.h>
#include <stdlib.h>

void DFS(int(* G)[10], int* visit, int N, int V) {
    
    
	visit[V] = 1;
	printf("%d ", V);
	for (int i = 0; i < N; i++) {
    
     //遍历每个临界点 对某个点的临界点来说,要按下三角矩阵遍历列
		if (G[i][V] == 1 && visit[i] != 1) {
    
    
			DFS(G, visit, N, i);
		}
	}
}

struct quee {
    
    
	int q[10];
	int front = 0;
	int rear = 0;
}Pq;

void Enquee(int V) {
    
    
	Pq.q[Pq.rear++] = V;
}

int Dequee() {
    
    
	return Pq.q[Pq.front++];
}

int IsEmpty() {
    
    
	if (Pq.front == Pq.rear)
		return 1;
	else
		return 0;
}

void BFS(int(* G)[10], int* visit, int N, int V) {
    
    
	visit[V] = 1;
	printf("%d ", V);
	Enquee(V);
	while(!IsEmpty()) {
    
    
		V = Dequee();	//以下遍历V的临接点
		for (int i = 0; i < N; i++) {
    
     //遍历每个临接点 对某个点的临接点来说,要按下三角矩阵遍历列
			if (G[i][V] == 1 && visit[i] != 1) {
    
    
				visit[i] = 1;
				printf("%d ", i);
				Enquee(i);
			}
		}
	}
}

int main() {
    
    
	int N, E;
	int a1, a2;
	scanf("%d %d", &N, &E);
	int G[10][10];
	for (int i = 0; i < E; i++) {
    
    
		scanf("%d %d", &a1, &a2);
		G[a1][a2] = 1;
		G[a2][a1] = 1;
	}
	//for (int i = 0; i < 44; i++) {
    
    
	//	printf("%d ", G[i]);
	//}
	int visit[10];
	for (int i = 0; i < N; i++) {
    
    
		visit[i] = 0;
	}
	for (int i = 0; i < N; i++) {
    
    
		if (visit[i] == 0) {
    
    
			printf("{ ");
			DFS(G, visit, N, i);
			printf("}\n");
		}
	}
	for (int i = 0; i < N; i++) {
    
    
		visit[i] = 0;
	}
	for (int i = 0; i < N; i++) {
    
    
		if (visit[i] == 0) {
    
    
			printf("{ ");
			BFS(G, visit, N, i);
			printf("}\n");
		}
	}
}

추천

출처blog.csdn.net/qq_43779658/article/details/105182993