7.6 列出连通集(BFS + DFS)
https://pintia.cn/problem-sets/15/problems/714
输入样例:
8 6
0 7
0 1
2 0
4 1
2 4
3 5
输出样例:
{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int n, m;
int flag = 0;
int map[15][15] = {0};
int visited[15] = {0};
queue<int> q;
void dfs(int s) {
visited[s] = 1;
if(!flag)
cout << "{";
printf(" %d", s);
for(int i = 0; i < n; i++)
if(!visited[i] && map[s][i] == 1) {
flag = 1;
dfs(i);
}
}
void bfs(int s) {
visited[s] = 1;
q.push(s);
while(!q.empty()) {
int l = q.front();
q.pop();
if(!flag)
cout << "{";
printf(" %d", l);
for(int i = 0; i < n; i++)
if(!visited[i] && map[l][i] == 1) {
visited[i] = 1;
q.push(i);
flag = 1;
}
}
}
int main() {
cin >> n >> m;
while(m--) {
int a, b;
cin >> a >> b;
map[a][b] = map[b][a] = 1;
}
for(int i = 0; i < n; i++)
if(!visited[i]) {
flag = 0;
dfs(i);
cout << " }" << endl;
}
memset(visited, 0, sizeof(visited));
for(int i = 0; i < n; i++)
if(!visited[i]) {
flag = 0;
bfs(i);
cout << " }" << endl;
}
return 0;
}
// 第二次做的时候也尝试了一下用并查集来选择连通分量的头结点,但是WA,分析了原因是因为并查集虽然能够将把节点链接起来但是在链接过程中却会导致头结点不唯一的情况,导致答案有所变化。嗯,对并查集的理解更加深了一些。
7-7 六度空间 (BFS)
https://pintia.cn/problem-sets/15/problems/715
输入样例:
10 9
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
输出样例:
1: 70.00%
2: 80.00%
3: 90.00%
4: 100.00%
5: 100.00%
6: 100.00%
7: 100.00%
8: 90.00%
9: 80.00%
10: 70.00%
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
#define N 1005
int n, m;
int map[N][N];
int visited[N];
int main() {
cin >> n >> m;
while(m--) {
int a, b;
cin >> a >> b;
map[a][b] = map[b][a] = 1;
}
for(int i = 1; i <= n; i++) {
memset(visited, 0, sizeof(visited));
visited[i] = 1;
queue<int> q;
q.push(i);
int level = 0;
int tail;
int last = i;
int cnt = 1;
while(!q.empty()) {
int l = q.front();
q.pop();
for(int j = 1; j <= n; j++)
if(!visited[j] && map[l][j] == 1) {
visited[j] = 1;
q.push(j);
tail = j;
cnt++;
}
if(last == l) {
last = tail;
level++;
}
if(level == 6) {
printf("%d: %.2lf%%\n", i, cnt*1.0/n*100.0);
break;
}
}
}
return 0;
}
// 没啥好说的,经典的练习BFS的题目,但是不知道为啥将BFS函数中的内容写在主函数里的一个循环就直接WA,理解不能。
7-33 地下迷宫探索(DFS)
https://pintia.cn/problem-sets/15/problems/860
输入样例1:
6 8 1
1 2
2 3
3 4
4 5
5 6
6 4
3 6
1 5
输出样例1:
1 2 3 4 5 6 5 4 3 2 1
输入样例2:
6 6 6
1 2
1 3
2 3
5 4
6 5
6 4
输出样例2:
6 4 5 4 6 0
#include <iostream>
#include <cstring>
using namespace std;
#define N 1005
int flag = 0;
int visited[N] = {0};
int n, m, s;
int map[N][N];
int cnt = 0;
void dfs(int s) {
visited[s] = true;
cnt++;
if(flag++)
cout << " ";
cout << s;
for(int i = 1; i <= n; i++)
if(map[s][i] && !visited[i]) {
dfs(i);
cout << " " << s;
}
}
int main() {
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
map[i][j] = 0;
cin >> n >> m >> s;
while(m--) {
int a, b;
cin >> a >> b;
map[a][b] = map[b][a] = 1;
}
dfs(s);
if(cnt < n)
cout << " " << 0;
return 0;
}
// 不多说了经典的DFS的题目,主要是输出格式比较绕人
7-36 社交网络图中结点的“重要性”计算(BFS + 并查集)
https://pintia.cn/problem-sets/15/problems/863
输入样例:
9 14
1 2
1 3
1 4
2 3
3 4
4 5
4 6
5 6
5 7
5 8
6 7
6 8
7 8
7 9
3 3 4 9
输出样例:
Cc(3)=0.47
Cc(4)=0.62
Cc(9)=0.35
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
#define N 10005
int map[N][N];
int visited[N] = {0};
int pre[N];
int n, m;
int find(int x) {
if(x != pre[x])
return pre[x] = find(pre[x]);
return x;
}
void Union(int x, int y) {
int a = find(x);
int b = find(y);
if(a != b)
pre[a] = b;
}
int BFS(int s) {
memset(visited, 0, sizeof(visited));
visited[s] = 1;
queue<int> q;
q.push(s);
int last = s;
int tail;
int level = 0;
int cnt = 0;
int sum = 0;
while(!q.empty()) {
int l = q.front();
q.pop();
for(int i = 1; i <= n; i++)
if(!visited[i] && map[l][i]) {
visited[i] = 1;
q.push(i);
cnt++;
tail = i;
}
if(last == l) {
last = tail;
level++;
sum += level*cnt;
cnt = 0;
}
}
return sum;
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
map[i][j] = 0;
for(int i = 1; i <= n; i++)
pre[i] = i;
while(m--) {
int a, b;
cin >> a >> b;
map[a][b] = map[b][a] = 1;
Union(a, b);
}
int cnt = 0;
for(int i = 1; i <= n; i++)
if(pre[i] == i)
cnt++;
int k;
cin >> k;
while(k--) {
int a;
cin >> a;
if(cnt > 1) {
printf("Cc(%d)=0.00\n", a);
} else {
printf("Cc(%d)=%.2f\n", a, 1.00*(n-1)/BFS(a));
}
}
return 0;
}
// 并查集判断图连通性并使用BFS计算每层的个数,六度空间的变式,思路通畅之后实现就很简单了。但是第二次做的时候再一次遇到相同的问题,思路完全一致,代码大概也一样,第一遍WA,删掉全部重写直接AC,理解不能。