A 第一题
- 求图的连通块个数,简单题啦,DFS 或 BFS 都可以。
- 题目的结点数目很大,故应使用邻接表存储结点。本题用数组 V 表示结点的存在与否,每当结点入队时,就将此结点抹去。参考代码如下。
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1000010;
bool V[maxn] = { false };
vector <int> adj[maxn];
void BFS(int n) {
queue <int> q;
q.push(n);
V[n] = false;
while (q.size()) {
int t = q.front();
q.pop();
for (int i = 0; i < adj[t].size(); i++) {
int temp = adj[t][i];
if (V[temp]) {
q.push(temp);
V[temp] = false;
}
}
}
}
int BFS_trave() {
int cnt = 0;
for (int i = 0; i < maxn; i++) {
if (V[i]) {
cnt++;
BFS(i);
}
}
return cnt;
}
int main() {
int a, b;
while (cin >> a >> b) {
adj[a].push_back(b);
adj[b].push_back(a);
V[a] = V[b] = true;
}
cout << BFS_trave() << endl;
return 0;
}
B 连通图
- 简单题啦,BFS 或 DFS 均可。这里使用一次 DFS 对图进行遍历,然后判断是否所有顶点都被访问到了,若还有未被访问到的顶点,则说明不是连通图,参考代码如下。
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1010;
bool V[maxn];
int G[maxn][maxn];
void DFS(int s, int n) {
if (V[s]) {
V[s] = false;
for (int i = 1; i <= n; i++) {
if (V[i] && G[s][i]) {
G[s][i] = G[i][s] = 0;
DFS(i, n);
}
}
}
}
int main() {
int n, m;
while (cin >> n >> m && n) {
fill(V, V + maxn, false);
for (int i = 0; i < maxn; i++)
fill(G[i], G[i] + maxn, 0);
for (int i = 1; i <= n; i++)
V[i] = true;
while (m--) {
int a, b;
cin >> a >> b;
G[a][b] = G[b][a] = 1;
V[a] = V[b] = true;
}
DFS(1, n);
bool flag = true;
for (int i = 1; i <= n; i++) {
if (V[i]) {
flag = false;
break;
}
}
if(flag)
cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}