请设计一个算法判断无向图G是否为一棵树,若是树,则返回1;否则,返回0。
解题思路:jt要注意无向图和有向图建图时的区别;用深搜遍历图,记录边数和顶点数,若边数=2*(顶点数-1),则是无向图树。因为在无向图里,每条边存了两次。
- #include
- #include
- #include
- using namespace std;
-
- const int MAXN=100;
- typedef struct ArcNode//边表结点
- {
- int adjvex;
- ArcNode *nextvex;
- };
-
- typedef struct Vnode//顶点表结点
- {
- int data;
- ArcNode *firstvex;
- };
-
- typedef struct Graph//图
- {
- Vnode adjlist[MAXN];
- int n;
- int e;
- }*graph;
-
- graph g=(graph)malloc(sizeof(Graph));
-
- void build(graph g)//用邻接表存储图
- {
- printf("n,e==");
- scanf("%d%d",&g->n,&g->e);
- for(int k=1;k<=g->n;k++)
- {
- g->adjlist[k].data=k;
- g->adjlist[k].firstvex=NULL;
- }
- printf("输入边边的from和to:\n");
- int i,j;
- for(int k=1;k<=g->e;k++)
- {
- scanf("%d%d",&i,&j);
- ArcNode *p=(ArcNode*)malloc(sizeof(ArcNode));
- p->adjvex=j;
- p->nextvex=g->adjlist[i].firstvex;
- g->adjlist[i].firstvex=p;
- //如果是有向图,则没有下面的代码
- ArcNode *q=(ArcNode*)malloc(sizeof(ArcNode));
- q->adjvex=i;
- q->nextvex=g->adjlist[j].firstvex;
- g->adjlist[j].firstvex=q;
- }
- }
-
- void print(graph g)//输出邻接表存储的图
- {
- for(int k=1;k<=g->n;k++)
- {
- printf("%d ",g->adjlist[k].data);
- ArcNode *p=g->adjlist[k].firstvex;
- while(p!=NULL)
- {
- printf("%d ",p->adjvex);
- p=p->nextvex;
- }
- printf("\n");
- }
- }
- int visit[100];//标记数组
- int nnum=0;//记录顶点数
- int ednum=0;//记录边条数
-
- void dfs(graph g,int v,int &nnum,int &ednum)//深搜
- {
- visit[v]=1;
- nnum++;
- ArcNode *p=g->adjlist[v].firstvex;
- while(p!=NULL)
- {
- ednum++;//p不为空说明存在一条边
- if(visit[p->adjvex]==0)
- {
-
- dfs(g,p->adjvex,nnum,ednum);
- }
- p=p->nextvex;
- }
-
-
- }
-
- bool isTree(graph g)
- {
- memset(visit,0,sizeof(visit));
- dfs(g,1,nnum,ednum);
- if(nnum==g->n&&ednum==2*(g->n -1)) return true;//无向图树的特点
- }
- int main()
- {
- build(g);
- print(g);
-
-
- if(isTree(g))
- {
- printf("是\n");
- }
- else printf("否\n");
- return 0;
- }
- /*非树测试数据
- 5 5
- 1 2
- 1 3
- 2 4
- 3 4
- 4 5
- */
-
- /*树测试数据
- 5 4
- 1 2
- 1 3
- 2 4
- 3 5
- */