#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
struct l_node
{
int ver;
struct l_node *link;//建立邻接表的结构
};
typedef struct l_node L_NODE;
typedef struct//图的边存储结构
{
int ver1;
int ver2;
}E_NODE;
L_NODE *head[1000005];//邻接表表头数组
int visit[1000005];//visit判断某顶点是否被访问过
E_NODE e[1000005];
int n,m;
void creat_adj_list(L_NODE *head[], E_NODE e[],int n,int m)//根据图的边存储生成邻接表
{
int i,u,v;
L_NODE *p;
for(i=1;i<=n;i++)
{
head[i]=NULL;//为邻接表的所有表头初始赋为null
}
for(i=0;i<m;i++)
{
u=e[i].ver1;
v=e[i].ver2;
p=(L_NODE*)malloc(sizeof(L_NODE));//建立一个节点
p->ver=v;//p的值为被指向的那个顶点
p->link=head[u];//将p加入到head[u]中
head[u]=p;
p=(L_NODE*)malloc(sizeof(L_NODE));//因为是无向的,每一产生两个节点
p->ver=u;
p->link=head[v];
head[v]=p;
}
}
void init(int n)//把visit数组各个元素置为0,表示为访问过
{
int i;
for(i=0;i<n;i++)
{
visit[i]=0;
}
}
void dfs(int u)//深度优先搜索递归调用
{
L_NODE *t;
visit[u]=1;//访问过后visit置为1
t=head[u];
while(t!=NULL)//单链表还没到尾时,继续递归调用
{
if(visit[t->ver]==0)
dfs(t->ver);
t=t->link;//如果已经被访问,向后移动一个节点
}
}
int main()
{
int m,n;
scanf("%d",&n);
scanf("%d",&m);
int i;
for(i=0;i<m;i++)
{
scanf("%d%d",&e[i].ver1,&e[i].ver2);//共有m组数据标示的边
}
int flag=0;
creat_adj_list(head,e,n,m);
init(n);
dfs(e[0].ver1);
for(i=1;i<=n;i++)//检验visit数组中所有元素是否都被访问
{
if(visit[i]==0)//如果有0,表示未被访问,则图不是连通的
flag=1;
}
if(flag==0)
printf("yes\n");
else printf("no\n");
}
牢记深度优先搜索的几个关键步骤。首先输入数据要存储在图的边存储结构中,然后再将图的边存储放入邻接表结构中,注意无向图每次应该生成两个节点,然后用dfs递归邻接表结构,使用visit数组标示顶点i是否被访问过。