找一个欧拉回路的路径问题
来源:互联网 发布:决策分析软件 编辑:程序博客网 时间:2024/05/17 00:50
若一个无向图存在欧拉回路,则图中所有的点的度数都为奇数的点的个数为2或0.
本题中,给定顶点数vertexNum,和每个点的度数degreeNum(当然这里的度数规定为偶数),且vertexNum>degreeNum。
则,必然存在欧拉回路。
#include<stdio.h>#define vertexNum20#define degreeNum10int upLimiteValue(int a, int b);void Drawing(int a[][vertexNum]);void print(int a[][vertexNum]);//定义一个邻接矩阵,记录无向图int matri[vertexNum][vertexNum];//定义一个矩阵,记录每个顶点的度数int ved[vertexNum];void Find_Euler_circuit(int a[][vertexNum]);void main(void){int i,j;//矩阵初始化,两个点有边为1,无边为0for(i=0; i<vertexNum; i++){ved[i]=0; /*每个顶点的度数初始化为0*/for(j=0; j<vertexNum; j++){matri[i][j]=0;}}Drawing(matri);print(matri);Find_Euler_circuit(matri);}//构造一个图void Drawing(int a[][vertexNum]){//先构造一棵树,思想:从起点开始,每个点依次与其他顶点相连,直到顶点度数为degreeNum则选择第二层的第一个点作为起点,连接那些还是孤立的//点,依次类推,第三层的第一个起点,第四层的第一个起点,每次都连接那些孤立的点来满足度数,这样可以保证所有的点已经连通。int i,j=1,k;int h;//求一下构造树的高度h=2+upLimiteValue(vertexNum-(degreeNum+1),(degreeNum-1));for(i=0; i<h; i++) //逐层构造{//查找每层的第一个起点的位置if(i==0 || i==1){k=i;}else if(i==2){k=k+degreeNum;}else{k=k+degreeNum-1;}for(; (ved[k]<degreeNum) && (j<vertexNum); j++){if(a[k][j]==0){a[k][j]=1;a[j][k]=1;ved[k]++;ved[j]++;}}}//把构造出的树中,所有的顶点的度数添加到degreeNumfor(i=0; i<vertexNum; i++){if(ved[i] != degreeNum){for(j=i+1; j<vertexNum && ved[i]!=degreeNum; j++){if(ved[j] != degreeNum && a[i][j]==0) {a[i][j]=1;a[j][i]=1;ved[i]++;ved[j]++;}}}}//补图的过程中,可能有些点的度没有达到规定的度数,需要再进行处理,这里可以得出未达到degreeNum的度一般都在最后,我们可以从后往前遍历for(i=vertexNum-1; ved[i]!=degreeNum; i--){//因为对度数进行补全时,是从前到后,所以未补全的度只能是最后一个点或两个点if(ved[i]%2 != 0) //假如当前度数是奇数,则前面的度数必然也是奇数{for(j=0; j<i && ved[i]!=degreeNum; j++){for(k=j+1; k<i; k++){if(a[i][j]==0 && a[i][k]==0 && a[i-1][j]==0 && a[i-1][k]==0 && a[j][k]==1){a[j][k]=0;a[k][j]=0;a[i][j]=1;a[j][i]=1;a[i-1][k]=1;a[k][i-1]=1;ved[i]+=1;ved[i-1]+=1;break;}}}}else{for(j=0; j<i && ved[i]!=degreeNum; j++){for(k=j+1; k<i; k++){if(a[i][j]==0 && a[i][k]==0 && a[j][k]==1){a[j][k]=0;a[k][j]=0;a[i][j]=1;a[j][i]=1;a[i][k]=1;a[k][i]=1;ved[i]+=2;break;}}}}}}//寻欧拉回路的思想:从起点开始走,编号小的优先,能得出一个个的小回路,把这些回路上的路径//按每个小回路得出来的先后次序//进行编号,直到所有边都遍历。然后再从起点开始走,先走回路编号的路径,然后选择定点编号小的走,//走完所有边,就能得出Euler回路void Find_Euler_circuit(int a[][vertexNum]){int i,j;int k=2; //标记回路号int base=0; int vNum=1;int road[(vertexNum*degreeNum)/2+1]={0};//记录每个小回路上的点int start=base;int mark=0; //标记已放入回路中的顶点号while(vNum<=(vertexNum*degreeNum)/2){if(ved[base]==0) //假如顶点的度数已满,则找下一个回路起点,回路号要+1{base=road[++mark];start=base;continue;}for(i=0; i<vertexNum; i++) //查找一个顶点编号最小的与其相邻的点{if(a[start][i]==1){a[start][i]=k;a[i][start]=k;ved[i]--;ved[start]--;road[vNum]=i;start=i;vNum++;break;}}if(start==base) //又回到起点,则完成一个回路,{k++;}}printf("*****************************************************\n");print(a);//开始寻找欧拉回路i=0;int bestchoice;int num=0;int jmark;printf("输出欧拉回路路径如下:");while(num<(vertexNum*degreeNum)/2){bestchoice=0;jmark=0;for(j=0; j<vertexNum; j++){if(a[i][j]>bestchoice){bestchoice=a[i][j];jmark=j;}}num++;printf("%d-->%d\t",i,jmark);a[i][jmark]=0;a[jmark][i]=0;i=jmark;}}//求上限值int upLimiteValue(int a, int b){if(a%b==0){return a/b;}else{return a/b+1;}}//打印矩阵void print(int a[][vertexNum]){int i,j;for(i=0; i<vertexNum; i++){for(j=0; j<vertexNum; j++){printf("%4d",a[i][j]);}printf("\n");}}
- 找一个欧拉回路的路径问题
- 欧拉回路--输出欧拉回路的路径
- 欧拉路径/回路
- 欧拉回路 欧拉路径某些问题集合
- HDU5883 欧拉路径与欧拉回路的判定
- 欧拉回路和欧拉路径的判断
- 欧拉回路路径求解
- 欧拉回路+路径 POJ
- 欧拉回路/路径【总结】
- 简单的欧拉回路算法问题
- 欧拉回路的构建及输出欧拉回路的路径
- 欧拉回路以及欧拉路径
- 欧拉路径&&欧拉回路
- 欧拉回路、欧拉路径
- 欧拉路径与欧拉回路
- hdu5348(欧拉回路+欧拉路径)
- 欧拉路径/欧拉回路
- 欧拉回路(欧拉路径)
- 11g relocate scan ip
- mysql inet_aton和inet_ntoa存储ip地址
- LinkedList集合的通常用法(一)
- qt creator开发qt Gui工程时,界面中文显示乱码
- Eclipse Java注释模板设置详解
- 找一个欧拉回路的路径问题
- andriod 上层实现预装apk
- java中实现百分比的计算与显示
- C++虚函数表解析(转) ——写的真不错
- 趣文:如何向外行解释机器学习和数据挖掘
- Spring
- 求并联后阻值大小
- 10款超实用的jQuery即时通知插件
- Hibernate 实体关联关系映射----总结