欧拉图
欧拉图定义
通过图(无向图或有向图)中所有边一次且仅一次行遍图中所有顶点的通路称为欧拉通路,通过图中所有边一次且仅一次行遍所有顶点的回路称为欧拉回路。具有欧拉回路的图称为欧拉图。
- 存在欧拉回路的图被称为欧拉图。
- 有欧拉通路,但无欧拉回路的图被称为半欧拉图。
- 欧拉路径:若存在一条从起点S出发的路径,经过每条边一次,但是不要求回到起点S。(类似一笔画)
欧拉图性质
- 有向图的欧拉回路:每个点的入度和出度都要相等
- 有向图的欧拉路径:起点度-1,终点度是1, 其余点为0
- 无向图的欧拉回路:每个点的度都是偶数
- 无向图的欧拉路径:只有两个点的度是奇数
判断欧拉图
判断图是欧拉图
针对有向图来说:
1.图G是连通的,不能有孤立的点存在。
2.每个顶点的入度要等于出度。
针对无向图来说:
1.图G是连通的,不能有孤立的点存在。
2.度数为奇数的点的个数为0。
判断图是半欧拉图
针对有向图来说:
1.图G是连通的,不能有孤立的点存在。
2.存在两个顶点,其入度不等于出度,其中一点出度比入度大1,为路径起点,另一点入度比出度大1,为路径的终点。
针对无向图来说:
1.图G是连通的,不能有孤立的点存在。
2.度数为奇数的点的个数为2,并且这两个点一定是路径的起点和终点。
献上总结丑图一份:
半欧拉图判断例题+题解: POJ1386
哈密顿图
哈密顿图定义
通过图的每个结点一次,且仅一次的通路(回路),就是哈密顿通路(回路)。存在哈密顿回路的图就是哈密顿图。
- 哈密顿回路:除了经过初始结点两次以外,通过图G的每个节点一次且仅一次的回路。
- 哈密顿通路:通过图G的每个节点一次且仅一次的通路。
- 哈密顿图:含有哈密顿回路的图。
- 竞赛图:有向完全图(任意两个顶点之间恰好有一条有向边)
哈密顿图性质
若图的最小度不小于顶点数的一半,则图是哈密顿图。
若图中每一对不相邻的顶点的度数之和不小于顶点数,则图是哈密顿图。
求哈密顿回路函数
//求汉密尔顿回路函数
int Hanmilton(){
int path[1000] = {0};
int cur_vertex = 0; //作为保存当前结点
int length = 0; //汉密尔顿回路长度
int min = 10000; //最小长度
for(int i = 1 ; i < this->Nv+1 ; i++){//对每个顶点为初始点进行比遍历寻找汉密尔顿回路
length = 0; //重新设置最端长度为0
memset(this->isvisited,0,sizeof(this->isvisited[0])*(this->Nv+1)); //重新初始化访问数组为0
this->isvisited[i] = 1; //标记当前结点为已访问
path[1] = i; //保存到临时路径数组的第一个
cur_vertex = i; //保存当前顶点
for(int j = 2 ; j < this->Nv+1 ; j++){//访问剩余的结点
int k = 0;
//寻找到第一个未访问的结点
for(k = 2 ; k < this->Nv+1 ; k++){
if(this->isvisited[k] == 0){
break;
}
}
int tmp = this->data[cur_vertex][k]; //保存当前顶点到该结点的路径长度
for(int m = k+1 ; m < this->Nv+1 ; m++){//向后寻找有没有路径更短的节点
if((!this->isvisited[m]) && (tmp > this->data[cur_vertex][m])){
tmp = this->data[cur_vertex][m];//更新当前最短路径
k = m;//更新第一个未被访问的结点
}
}
path[j] = k; //保存路径上的结点
this->isvisited[k] = 1; //标记为已访问
cur_vertex = k; //跟新当前结点
length += tmp; //跟新长度
if(length > min){ //当前长度大于最小长度,则改路径无效,跳出循环
break;
}
}
length += this->data[cur_vertex][i];
if(min > length){ //更新最小长度并保存最佳路径
min = length;
for(int m = 0 ; m < this->Nv+1 ; m++){
this->best_path[m] = path[m];
}
}
}
//返回最小长度
return min;
}
void Print_Best_Path(){ //打印最佳汉密尔顿回路
cout<<this->best_path[1];
for(int i = 2 ; i < this->Nv+1 ; i++){
cout<<" -> "<<this->best_path[i];
}
cout<<" -> "<<this->best_path[1];
}