Skip to content

Latest commit

 

History

History
277 lines (259 loc) · 4.52 KB

1013.md

File metadata and controls

277 lines (259 loc) · 4.52 KB

1013

dfs and 并查集

1 Key Points

  • 森林中, 连通分量的个数 = 树的个数 = 节点个数 - 边的条数, 但是在==图中却不一定==, 因为图中可能存在环.
  • 图的dfs
void dfs(int i) {
	visited[i] = 1;
	for (int j = 1; j <= N; j++) {
		if (visited[j] == 0 && g[i][j] == 1) {
			dfs(j);
		}
	}
}
  • 容器建立和赋值
#include <vector>
#include <algorithm>
vector<int> visited(1000, 0);
fill(visited.begin(), visited.end(), 0);
  • 并查集
#include <cctype>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
// #include <bits/stdc++.h>
using namespace std;
typedef long long ll;


const int maxN = 1000 + 5;
int Tree[maxN];
struct w {
	int x;
	int y;
} way[maxN * maxN / 2];

int findRoot(int x) {
	if (Tree[x] == -1) {
		return x;
	}
	else {
		Tree[x] = findRoot(Tree[x]);
		return Tree[x];
	}
}

int main() {
	way[0].x = 1;
	way[0].y = 2;
	way[1].x = 1;
	way[1].y = 3;
	way[2].x = 4;
	way[2].y = 5;
	way[3].x = 4;
	way[3].y = 6;
	way[4].x = 5;
	way[4].y = 6;
	//	 1
	//  / \
    // 2   3
	//	 4
	//  / \
    // 5---6
	int N = 6;
	int M = 5;
	for (int i = 0; i <= N; i++) {
		Tree[i] = -1;
	}
	for (int i = 0; i < M; i++) {
		int rx = findRoot(way[i].x);
		int ry = findRoot(way[i].y);
		// cout << rx << "  " << ry << endl;
		if (rx != ry) {
			Tree[rx] = ry;
		}
	}
	for (int i = 1; i <= N; i++) {
		cout << i << "  ";
	}
	cout << endl;
	for (int i = 1; i <= N; i++) {
		cout << Tree[i] << "  ";
	}
	cout << endl;
	int group = 0;
	for (int i = 0; i < N; i++) {
		if (Tree[i] == -1) {
			group++;
		}
	}
	cout << group << endl;
	/*
	1  2  3  4  5  6
	2  3  -1  5  6  -1
	2
	*/
	return 0;
}

2 Answers

  • 方法1: dfs
#include <cctype>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
// #include <bits/stdc++.h>
using namespace std;
typedef long long ll;


const int maxN = 1000 + 5;
int g[maxN][maxN] = { 0 };
vector<int> visited(maxN, 0);
int N, M, K;

void dfs(int i) {
	visited[i] = 1;
	for (int j = 1; j <= N; j++) {
		if (visited[j] == 0 && g[i][j] == 1) {
			dfs(j);
		}
	}
}

int main() {
	cin >> N >> M >> K;
	for (int i = 0; i < M; i++) {
		int a, b;
		cin >> a >> b;
		g[a][b] = g[b][a] = 1;
	}
	/*
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			cout << g[i][j] << " ";
		}
		cout << endl;
	}
	// */
	for (int k = 0; k < K; k++) {
		int destroyed;
		cin >> destroyed;
		int num = 0;
		fill(visited.begin(), visited.end(), 0);
		visited[destroyed] = 1;
		for (int i = 1; i <= N; i++) {
			if (visited[i] == 0) {
				num++;
				dfs(i);
			}
		}
		cout << num - 1 << endl;
	}
	return 0;
}
  • 方法2: 并查集
#include <cctype>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
// #include <bits/stdc++.h>
using namespace std;
typedef long long ll;


const int maxN = 1000 + 5;
int Tree[maxN];
struct w {
	int x;
	int y;
} way[maxN * maxN / 2];

int findRoot(int x) {
	if (Tree[x] == -1) return x;
	else {
		int tmp = findRoot(Tree[x]);
		Tree[x] = tmp;
		return tmp;
	}
}

int main() {
	int N, M, K;
	scanf("%d%d%d", &N, &M, &K);
	for (int i = 0; i < M; i++) {
		scanf("%d%d", &way[i].x, &way[i].y);
	}
	for (int k = 0; k < K; k++) {
		for (int i = 1; i <= N; i++) {
			Tree[i] = -1;
		}
		int c;
		scanf("%d", &c);
		for (int i = 0; i < M; i++) {
			if (way[i].x != c && way[i].y != c) {
				int rx = findRoot(way[i].x);
				int ry = findRoot(way[i].y);
				if (rx != ry) {
					Tree[rx] = ry;
				}
			}
		}
		int group = 0;
		for (int i = 1; i <= N; i++) {
			if (Tree[i] == -1) {
				group++;
			}
		}
		printf("%d\n", group - 2);
	}
	return 0;
}


/*
Sample Input:
3 2 3
1 2
1 3
1 2 3
Sample Output:
1
0
0
*/

References

  1. PAT 1013. Battle Over Cities - A-Little-Nut - 博客园
  2. PAT 1013. Battle Over Cities(25) - Steve Sun的专栏 - CSDN博客
  3. 并查集 - CYJB - 博客园