Saki也想要变强之Saki的一日一题(3)
上个星期由于基物实验要期中考试,一个星期我都在复习基物实验(所以为什么软件工程专业的我要学基物实验。。。)所以一个星期没打代码了。这个星期继续学习。
【问题描述】
给定一个无向图和一个图顶点,编程输出该图删除给定顶点前后按深度优先遍历及广度优先遍历方式遍历的图顶点序列。
给定的无向图和图顶点满足以下要求:
1、无向图的顶点个数n大于等于3,小于等于100,输入时顶点编号用整数0~n-1表示;
2、无向图在删除给定顶点前后都是连通的;
3、无论何种遍历,都是从编号为0的顶点开始遍历,访问相邻顶点时按照编号从小到大的顺序访问;
4、删除的顶点编号不为0。
【输入形式】
先从标准输入中输入图的顶点个数和边的个数,两整数之间以一个空格分隔,然后从下一行开始分行输入每条边的信息(用边两端的顶点编号表示一条边,以一个空格分隔顶点编号,边的输入次序和每条边两端顶点编号的输入次序可以是任意的,但边不会重复输入),最后在新的一行上输入要删除的顶点编号。
【输出形式】
分行输出各遍历顶点序列,顶点编号之间以一个空格分隔。先输出删除给定顶点前的深度优先遍历顶点序列和广度优先遍历顶点序列,再输出删除给定顶点后的深度优先遍历顶点序列和广度优先遍历顶点序列。
代码:
include<stdio.h>
include<limits.h>
include<stdio.h>
int graph[1000][1000],q[1000],tail,head,time;
struct tnode{
int visit;
int d;
int f;
int pi;
};
struct tnode vertex[1000];
void enqueue(int *q,int x){
q[tail]=x;
tail++;
}
int dequeue(int *q){
int x;
x = q[head];
head++;
return x;
}
void BFS(int n,int s){
int i,u,v;
for(i=1;i<=n;i++){
vertex[i].visit=0;
vertex[1000].d=INT_MAX;
}
vertex[s].visit=1;
//printf("%d ",s);
vertex[s].d=0;
tail = 0;
head = 0;
enqueue(q, s);
while(tail!=head){
u = dequeue(q);
for(i = 0; i < n;i ++){
if(graph[u][i] == 1){
if(vertex[i].visit==0){
vertex[i].visit = 1;
vertex[i].d = vertex[u].d + 1;
vertex[i].pi = u;
enqueue(q,i);
}
}
}
printf("%d ", u);
//vertex[u].visit = 1;
}
}
void DFS_visit(int n,int i){
int j;
time++;
vertex[i].d = time;
vertex[i].visit = 1;
printf("%d ", i);
for (j = 0; j < n;j++){
if(graph[i][j]1){
if(vertex[j].visit0){
vertex[j].pi = i;
DFS_visit(n, j);
}
}
}
time++;
vertex[i].f = time;
}
void DFS(int n,int det){
int i;
for (i = 0; i < n;i++){
vertex[i].visit = 0;
}
time = 0;
if(det-1){
for (i = 0; i < n;i ++){
if(vertex[i].visit0){
DFS_visit(n, i);
}
}
}
else{
for (i = 0; i < n;i++){
if(i!=det){
if(vertex[i].visit0){
DFS_visit(n, i);
}
}
}
}
}
int main()
{
int n,m,i,j,v1,v2,det;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
scanf("%d%d",&v1,&v2);
graph[v1][v2]= graph[v2][v1]= 1;
}
scanf("%d",&det);
DFS(n,-1);
printf("\n");
BFS(n,0);
printf("\n");
for (i = 0; i < n;i++){
graph[det][i] = 0;
graph[i][det] = 0;
}
DFS(n,det);
printf("\n");
BFS(n,0);
printf("\n");
}
心得:
基础的图算法,广度优先遍历与深度优先遍历,由于我上学期数据结构在摸鱼,所以不得不重新学习了一遍图算法,本题在将节点颜色改变时打印当前节点即可。至于删除节点后的操作,如果是用链表来储存图的话没什么好说的了,但用数组来储存图的话就需要注意:深度优先遍历会将每个节点都遍历一遍,不能简单的将矩阵中的数值改为0,我用的方法是给DFS函数添加一个参数,跳过需要删除的节点。
即:
if(i!=det){
if(vertex[i].visit0){
DFS_visit(n, i);
}
}


浙公网安备 33010602011771号