给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式:
输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。
输出格式:
按照"{ v1 v2 ... vk }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。
输入样例:
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 }
作者: 陈越
单位: 浙江大学
时间限制: 400ms
内存限制: 64MB
代码长度限制: 16KB
个人分析:题目意思很明确,用DFS/BFS(深度/广度优先遍历)分别遍历输入的无向图,判别该无向图具有多少个不联通的子集。基本就是课件里代码练习,直接上代码:
#include<stdio.h>
#include<stdlib.h>
#define INFINITY 65535
#define MaxVertexNum 10
typedef int Vertex;
typedef int weightType;
int Visit[MaxVertexNum]={0}; //0为未访问,1为已访问
//边结构定义
typedef struct ENode *Edge;
struct ENode{
Vertex v1,v2;
weightType weight;
};
//图结构定义
typedef struct GNode *MGraph;
struct GNode{
int Nv; //顶点数
int Ne; //边数
weightType G[MaxVertexNum][MaxVertexNum];
};
//队列定义
typedef struct QNode *Queue;
struct QNode{
int *Data;
int Front,Rear;
int Maxsize;
};
Queue CreateQueue(int Maxsize)
{
Queue Q=(Queue)malloc(sizeof(struct QNode));
Q->Data=(int *)malloc(Maxsize*sizeof(int));
Q->Front=Q->Rear=0;
Q->Maxsize=Maxsize;
return Q;
}
void Add(Queue Q,int X)
{
if((Q->Rear+1)%Q->Maxsize!= Q->Front)
{
Q->Rear = (Q->Rear+1)%Q->Maxsize;
Q->Data[Q->Rear] = X;
}
}
bool IsEmpty(Queue Q)
{
return (Q->Front==Q->Rear);
}
int Delete(Queue Q)
{
if(!IsEmpty(Q))
{
Q->Front =(Q->Front+1)%Q->Maxsize;
return Q->Data[Q->Front];
}
}
//图初始化函数
MGraph CreateGraph(int VertexNum)
{
Vertex V,W;
MGraph Graph;
Graph=(MGraph)malloc(sizeof(struct GNode));
Graph->Nv=VertexNum;
Graph->Ne=0;
for(V=0;V<Graph->Nv;V++)
{
for(W=0;W<Graph->Nv;W++)
{
Graph->G[V][W]=INFINITY;
}
}
return Graph;
}
//边插入函数
void InsertEdge(MGraph Graph,Edge E)
{ //无向图插入
Graph->G[E->v1][E->v2]=E->weight;
Graph->G[E->v2][E->v1]=E->weight;
}
//由输入,构造对应的邻接矩阵图
MGraph BuildGraph()
{
MGraph Graph;
Edge E;
Vertex V;
int Nv,i;
scanf("%d",&Nv);//读入结点数
Graph=CreateGraph(Nv);
scanf("%d",&Graph->Ne);//读入边数
getchar();
if(Graph->Ne>0)
{
E=(Edge)malloc(sizeof(ENode));
for(i=0;i<Graph->Ne;i++)
{
scanf("%d %d",&E->v1,&E->v2);
E->weight=1;
getchar();
InsertEdge(Graph,E);
}
free(E);
}
return Graph;
}
void DFS(MGraph Graph,Vertex num)
{
int i;
if(Visit[num]==0)
{
printf("%d ",num);
Visit[num]=1;
}
for(i=0;i<Graph->Nv;i++)
{
if(Graph->G[num][i]==1&&Visit[i]==0) //若num与i俩结点连通,才能进行遍历
{
DFS(Graph,i);
}
}
}
void DSPListComponents(MGraph Graph)
{
int k;
for(k=0;k<Graph->Nv;k++)
{
if(!Visit[k])
{
printf("{ ");
DFS(Graph,k);
printf("}\n");
}
}
}
void BSP(MGraph Graph,int i)
{
int num;
Queue q=CreateQueue(Graph->Nv);
Add(q,i);
Visit[i]=1;
printf("%d ",i);
while(!IsEmpty(q))
{
num=Delete(q);int k;
for(k=0;k<Graph->Nv;k++)
{
if(Graph->G[num][k]==1&&Visit[k]==0)
{
Add(q,k);
Visit[k]=1;
printf("%d ",k);
}
}
}
}
void BSPListComponents(MGraph Graph)
{
int k;
for(k=0;k<Graph->Nv;k++)
{
if(!Visit[k])
{
printf("{ ");
BSP(Graph,k);
printf("}\n");
}
}
}
int main()
{
MGraph Graph=BuildGraph(); //建立输入对应的图
DSPListComponents(Graph); //DSP遍历,输出最大连通集
for(int i=0;i<Graph->Nv;i++) //初始化Visit数组
Visit[i]=0;
BSPListComponents(Graph); //BSP遍历,输出最大连通集
return 0;
}
测试结果:
总结:终于是更到图论了,再接再厉,6.1号就答辩完了,之后能一心一意搞定数据结构了!!