这道题是个图的入门题,其过程就是将图建立出来,然后对这个图进行两种遍历。
其实就三步:
1.建立图(邻接矩阵):
struct GNode{
int N;
int E;
int map[11][11];
};
typedef GNode* UnicomSet;
UnicomSet MAP;
void GreateMap(int n,int m){
MAP = (UnicomSet)malloc(sizeof(struct GNode));
MAP -> N = n;
MAP -> E = m;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
MAP->map[i][j] = 0;
}
}
while(m--){
int a,b;
cin>>a>>b;
MAP->map[a][b]=1;
MAP->map[b][a]=1;
}
return;
}
2.深度遍历,就是只要两点有边事就递归出来然后打印然后用visD数组保存一下已经遍历过的事实即可。(类比于树的先序遍历)
void Dfs(int start,int n){
cout<<start<<" ";
visD[start] = 1;
for(int j=0;j<n;j++){
if(visD[j]!=1&&MAP->map[start][j]==1){
Dfs(j,n);
}
}
return;
}
3.广度遍历,将第一个节点压入队列,然后循环遍历,和第一个节点有边的节点就压入队列(并用visB数组记录一下已经遍历过的事实)(类比于树的层序遍历)
void Bfs(int start,int n){
cout<<"{ ";
int hh = 0,tt = -1;
queue[++tt] = start;
visB[start] = 1;
while(tt >= hh){
int i = queue[hh++];
for(int j=0;j<n;j++){
if(MAP->map[i][j]==1&&visB[j]!=1){
queue[++tt] = j;
visB[j] = 1;
}
}
}
for(int i=0;i<=tt;i++)
cout<<queue[i]<<" ";
cout<<"}"<<endl;
return;
}
然后这是全部的代码
#include <iostream>
using namespace std;
struct GNode{
int N;
int E;
int map[11][11];
};
typedef GNode* UnicomSet;
UnicomSet MAP;
int visB[11];
int visD[11];
int queue[11];
void GreateMap(int n,int m){
MAP = (UnicomSet)malloc(sizeof(struct GNode));
MAP -> N = n;
MAP -> E = m;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
MAP->map[i][j] = 0;
}
}
while(m--){
int a,b;
cin>>a>>b;
MAP->map[a][b]=1;
MAP->map[b][a]=1;
}
return;
}
void Bfs(int start,int n){
cout<<"{ ";
int hh = 0,tt = -1;
queue[++tt] = start;
visB[start] = 1;
while(tt >= hh){
int i = queue[hh++];
for(int j=0;j<n;j++){
if(MAP->map[i][j]==1&&visB[j]!=1){
queue[++tt] = j;
visB[j] = 1;
}
}
}
for(int i=0;i<=tt;i++)
cout<<queue[i]<<" ";
cout<<"}"<<endl;
return;
}
void Dfs(int start,int n){
cout<<start<<" ";
visD[start] = 1;
for(int j=0;j<n;j++){
if(visD[j]!=1&&MAP->map[start][j]==1){
Dfs(j,n);
}
}
return;
}
int main(){
int n,m;
int a,b;
cin>>n>>m;
GreateMap(n,m);
for(int i=0;i<n;i++){
if(!visD[i]){
cout<<"{ ";
Dfs(i,n);
cout<<"}"<<endl;
}
}
for(int i=0;i<n;i++){
if(!visB[i])Bfs(i,n);
}
return 0;
}
邻接表
解释一下为啥不用邻接表来建立,我试过了,过不了这道题感觉,因为判题机就是将我们输出的结果和电脑服务器中的样例对比一下,所以说我们如果输入的顺序不一样的话也是过不了的。
下面是我写的邻接表的代码
#include <iostream>
using namespace std;
#define N 100
//邻接表
struct Node{
int id;
Node *next;
Node(int _id):id(_id),next(NULL){}
}*head[N];
void add(int a,int b){
auto B = new Node(b);
auto A = new Node(a);
B->next = head[a];
A->next = head[b];
head[a] = B;
head[b] = A;
}
int visB[N];
int visD[N];
int queue[1000];
void Bfs(int start,int n){
int hh =0 , tt = -1;
queue[++tt] = start;
while(hh <= tt){
int end = queue[hh++];
if(visB[end]==0){
cout<<end<<" ";
visB[end]=1;
}
for(auto p = head[end];p;p=p->next){
if(visB[p->id]==0){
cout<<p->id<<" ";
visB[p->id]=1;
queue[++tt] = p->id;
}
}
}
return;
}
void Dfs(int start,int n){
if(visD[start]==0){
visD[start] = 1;
cout<<start<<" ";
}
for(auto p=head[start];p;p=p->next){
if(visD[p->id]==0){
Dfs(p->id,n);
}
}
return;
}
int main(){
int n,m;
int a,b;
cin>>n>>m;
//建立表
while(m--){
cin>>a>>b;
add(a,b);
}
for(int i=0;i<n;i++){
if(!visD[i]){
cout<<"{ ";
Dfs(i,n);
cout<<"}"<<endl;
}
}
for(int i=0;i<n;i++){
if(!visB[i]){
cout<<"{ ";
Bfs(i,n);
cout<<"}"<<endl;
}
}
return 0;
}
这种方式出来的答案如下,所以就会判我们错,所以不用尝试了,这道题只能用邻接矩阵写。