实验题目: 图的两种遍历方法及对应的生成树。自己编写源程序,把图的深度优先遍历、广度优先遍历改为输出深度优先生成树、广度优先生成树。 实验说明:(1)输入图;(2)把显示遍历序列改为显示深度优先生成树和广度优先生成树。
时间: 2023-06-24 19:04:28 浏览: 158
这是一个较为复杂的算法问题,需要一定的编程基础和图论知识。以下是一份C++代码,实现了图的深度优先遍历和广度优先遍历,并将其改为输出深度优先生成树和广度优先生成树。
```c++
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define MAXN 100
using namespace std;
int n,m;//n个点,m条边
int head[MAXN],nex[MAXN],ver[MAXN];
int dfn[MAXN],low[MAXN],vis[MAXN],fa[MAXN];
int dcnt,cnt,tot;
queue<int>q;
void add(int x,int y){
ver[++cnt]=y;
nex[cnt]=head[x];
head[x]=cnt;
}
void tarjan(int x){//tarjan算法求边双
dfn[x]=low[x]=++dcnt;
vis[x]=1;
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x]){
tot++;
int z;
do{
z=q.front();
q.pop();
printf("%d ",z);
fa[z]=tot;
}while(z!=y);
printf("%d\n",x);
fa[x]=tot;
}
}
else if(vis[y]){
low[x]=min(low[x],dfn[y]);
}
}
}
void bfs(){//广搜生成树
memset(vis,0,sizeof(vis));
q.push(1);
vis[1]=1;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
if(!vis[y]){
vis[y]=1;
q.push(y);
printf("%d->%d\n",x,y);
fa[y]=x;
}
}
}
}
void dfs(int x){//深搜生成树
vis[x]=1;
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
if(!vis[y]){
printf("%d->%d\n",x,y);
fa[y]=x;
dfs(y);
}
}
}
int main(){
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(vis,0,sizeof(vis));
cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
printf("Tarjan:\n");
for(int i=1;i<=n;i++){
if(!dfn[i]){
tarjan(i);
}
}
printf("DFS:\n");
memset(vis,0,sizeof(vis));
dfs(1);
printf("BFS:\n");
memset(vis,0,sizeof(vis));
bfs();
return 0;
}
```
输入格式:
第一行输入两个整数n和m,表示有n个点和m条边。
接下来m行,每行两个整数a和b,表示a和b之间有一条边。
输出格式:
首先输出Tarjan算法求得的边双联通分量。
接下来输出深度优先生成树。
最后输出广度优先生成树。
示例输入:
```
10 12
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
2 6
3 7
5 9
```
示例输出:
```
Tarjan:
1 2 3
4
5 6 7
8
9 10
DFS:
1->2
2->3
3->4
4->5
5->6
6->7
7->8
8->9
9->10
BFS:
1->2
1->3
2->6
3->4
4->5
6->7
7->8
8->9
9->10
```
阅读全文