- 1、本文档共4页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
(一)问题对一个有向图,请编一程序判断是否是根树,如是根树给出根结点的序号。所谓根树,一种简单的定义是指: 该有向图中存在一点,该点至该图中任意其他点都存在且仅存在一条通路,并且不存在反向通路的有向图,这一特殊的点称为该根树的根。如图1 就不是一棵根树,而图2则是一棵根树。
(二) 分析首先,不难得到如下几个结论。结论1:复杂图,即含平行边(两边起点与终点都相同)或含环(一边的两顶点是同一顶点),一定不是根树。结论2:根树有且只有1个入度为0的点,该点就是根树的根。结论3:只有1个顶点且没有任何边的图是根树。结论4: 对一个根树,每一个分支也一定是一棵根树。即去掉根树的根点及由根引出的所有n条边,那么得到的图将是由n条被去掉边的终点为根的根树组成的森林图。反过来,n棵根树再加入1点,并由该点到每一根树的根加入一条边,则一定得到一棵根树。结论3与结论4合在一起,实际上给出了根树的另一种与上述定义等价的递归方式的定义,同时也给出了一种判断根树的方法,这也是下面给出的参考程序所采用的方法。
(三)程序设计这里,我为大家提供一个参考程序,基本的判断过程简单说明如下。首先,读入有向图数据,边读边判断是否存在平行边与环,有则判为不是根树。第二步,遍历每个顶点是否是入度为0的点,个数不为1则判不为根树,否则设入度为0的点是惟一的可能为根树的点,也是下面递归判断的起始点, 故设当前搜寻点序号变量值id 为该点序号。第三步,递归法判断是否为根树。对每一点的遍历搜寻状态设一数组nk[n],nk[i]0表示该点还未遍历,1 表示已遍历,初始全置为0。程序通过递归函数dtree()完成分析,递归函数完成以id为假设根的一个有向图是否为独立根树的判断。递归函数首先检查假设根点的入度,非0 则判为非根树。然后对每一点依次循查并完成以下工作:如有边指向该点,如指向点已搜寻过(即nk[i]非0)则判为非根树,否则,将该点标为已搜寻过(即置nk[i]为1),去掉该边,设下一轮假设根为该指向点,再调本递归函数对该分支是否为根树进行递归判断。第四步,通过递归分析后,再检查是否所有点已遍历完,没有判为非根树,已遍历完则判为根树。
(四)源程序/* 该程序用于判断有向图是否为一根树,如为根树则给出根结点序号罗光宣 2001.1.25 VC6.0通过 */#include stdio.h#include stdlib.h// 读入有向图的数据int rdata(char *fn,int *n,int *m,int ***pd){FILE *fp;int i,j,k;if( (fp=fopen(fn,r))==NULL ){ printf(文件%s打不开!,fn);return(-1);}fscanf(fp,%d %d,n,m);if(*n=0 || *m0){printf(输入文件%s的数据不合法!,fn);return(-2);}if((*pd=(int **)malloc((*n)*sizeof(int *)))0)exit(1);for(i=0;i*n;++i){ if(( (*pd)[i]=(int *)malloc((*n)*sizeof(int)))==NULL)exit(1);for(j=0;j*n;++j)(*pd)[i][j]=0;}for(i=0;i*m;++i){ fscanf(fp,%d %d,j,k);if(j=*n || j0 || k=*n || k0){ printf(输入文件%s的数据不合法!,fn);return(-3);}if((*pd)[j][k]!=0 || j==k){ printf(该图含平行边或带环,不可能是根树!);return(-20);}// 平行边与环(*pd)[j][k]=1;}fclose(fp);return(1);}// 该函数用递归法判断图是否为根树int dtree(int id,int n,int **pd,int *nk){int i,nt,h;for(i=0,nt=0;in;++i)if(pd[i][id]0)++nt;if(nt0)return(-1);for(i=0;in;++i)if(pd[id][i]0){ if(nk[i])return(-2);nk[i]=1;++nt;pd[id][i]=0;if((h=dtree(i,n,pd,nk))0)return(h);}return(1);}void main(void){int id,i,j,n,m,nt,nv,**pd,*nk;if(rdata(input.dat,n,m,pd)0)exit(1);nk=(int *)ma
文档评论(0)