实验主题
可简单图化、连通图、欧拉图和哈密顿图的判断
实验目的
1、掌握可简单图化的定义及判断方法;
2、掌握连通图、欧拉图的判断方法;
3、掌握欧拉回路的搜索方法;
4、了解欧拉图的实际应用。
实验要求
1、给定一非负整数序列(例如:(4,2,2,2,2))判断此非负整数序列是否是可图化的,是否是可简单图化的。
2、如果是可简单图化的,根据Havel定理过程求出对应的简单图,并输出此图。
3、判断此简单图是否是连通的。
4、如果是连通图,判断此图是否是欧拉图。如果是欧拉图,请输出一条欧拉回路(输出形式如:v2→v1→v5→v3→v4→v5→v2)。
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
const int MAX = 10;
int tem[MAX][MAX];
stack<int> s;
class Node
{
public:
Node();
~Node();
int id, degree;
private:
};
Node::Node()
{
}
Node::~Node()
{
}
bool cmp(Node x, Node y)
{
return x.degree > y.degree;
}
class situation
{
public:
situation(int count);
~situation();
int count;
Node* node = new Node[MAX];
int adjMatrix[MAX][MAX];
bool _isGraph = false;
bool _isGraphizableCheck = false;
void init()
{
cout << "请输入度数序列" << endl;
for (int i = 1; i <= count; i++)
{
cin >> node[i].degree;
node[i].id = i;
}
}
void copyList(Node* tNode) {
for (int i = 1; i <= count; i++)
{
tNode[i].degree = node[i].degree;
tNode[i].id = node[i].id;
}
}
void graphizableCheck()
{
int sum = 0;
for (int i = 1; i <= count; i++)
{
if(node[i].degree>=0)
sum+=node[i].degree;
else
{
cout << "有负数度,不可图化" << endl;
break;
}
}
if (sum % 2)
{
cout << "不可图化" << endl;
return;
}
cout << "可图化" << endl;
_isGraph = true;
sort(node + 1, node + count + 1,cmp);
if (node[0].degree > count - 1)
{
cout << "不可简单图化" << endl;
return;
}
else
{
//Havle的等价定理
for (int i = 1; i <= count; i++)
{
int left = 0;
for (int index = 1; index <= i; index++)
{
left += node[index].degree;
}
int right = i * (i - 1);
for (int index = i + 1; index <= count; index++)
{
right += min(i, node[index].degree);
}
if (left > right)
{
cout << "不可简单图化" << endl;
return;
}
}
}
cout << ",可简单图化" << endl;
_isGraphizableCheck = true;
}
//判断
bool flag(Node *nNode,int s,int n)
{
int sum = 0;
for (int i = s; i <= n; i++)
{
sum += nNode[i].degree;
}
if (!sum)return true;
else return false;
}
//Havle定理求出简单图
void Havle()
{
int l = 1;
int r = count;
Node* nNode = new Node[count + 1];
copyList(nNode);
cout << "(";
for (int i=l; i <= count; i++)
{
cout << nNode[i].degree;
if (i != count)cout << ",";
}
cout << ")";
cout << "可简单图化" << endl;
//后面l位都减一
while (!flag(nNode,l, r))
{
for (int i = l + 1; i <= l + nNode[l].degree; i++)
{
nNode[i].degree--;
}
sort(nNode + 1 + l, nNode + 1 + count, cmp);
l++;
cout << "<=>";
cout << "(";
for (int i = l; i <= r; i++)
{
cout << nNode[i].degree;
if (i != r)cout << ",";
}
cout << ")";
cout << "可简单图化" << endl;
}
delete[] nNode;
}
bool constructSimpleGraph()
{
cout << "构造简单图" << endl;
Node* nNode = new Node[count + 1];
copyList(nNode);
//直接做出简单图
for (int i = 1; i <= count; i++)
{
sort(nNode + i, nNode + 1 + count, cmp);
if (nNode[i].degree > count - i)return false;
for (int j = i + 1; j <= i + nNode[i].degree; j++)
{
if (!nNode[j].degree) return false;
nNode[j].degree--;
adjMatrix[nNode[i].id][nNode[j].id] = 1;
adjMatrix[nNode[j].id][nNode[i].id] = 1;
}
nNode[i].degree = 0;
}
cout << "index";
for (int i = 1; i <= count; i++)
{
printf("%5d", i);
}
cout << endl << endl;
for (int i = 1; i <= count; i++) {
printf("%5d", i);
for (int j = 1; j <= count; j++) {
printf("%5d", adjMatrix[i][j]);
}
cout << endl;
}
delete[] nNode;
return true;
}
int visited[MAX] = {0};
int p_sum = 0;
void tem_adjMartix()
{
for (int i = 1; i <= count; i++)
{
for (int j = 1; j <= count; j++)
{
tem[i][j] = adjMatrix[i][j];
}
}
}
void DFS(int x)
{
if (visited[x] == 0)p_sum++;
visited[x] = 1;
for (int i = 1; i <= count; i++)
{
if (tem[x][i] == 1)
{
tem[x][i] = tem[i][x] = 0;
DFS(i);
break;
}
}
return;
}
bool _isConnected()
{
tem_adjMartix();
DFS(1);
if (p_sum==count)
{
// cout << p_sum << endl;
return true;
}
else
{
// cout << p_sum << endl;
return false;
}
}
bool Eular()
{
int oddNum = 0;
for (int i=1; i < count; i++)
{
if (node[i].degree % 2)oddNum++;
}
if (oddNum == 0)return true;
else return false;
}
void DFS_1(int x)
{
node[x].degree--;
cout << "v" << x << "->";
int max = max_degree(x);
if (node[max].degree != 0)
{
adjMatrix[x][max] = adjMatrix[max][x] = 0;
DFS_1(max);
}
}
int max_degree(int x)
{
int maxnode = 0;
node[maxnode].degree = 0;
for (int i = 1; i <= count; i++)
{
if (adjMatrix[x][i] == 1 && node[i].degree > node[maxnode].degree)
maxnode = i;
}
return maxnode;
}
//hierholzer算法
void eularCircuit(int start)
{
DFS_1(start);
cout << "done";
}
private:
};
situation::situation(int count)
{
this->count = count;
}
situation::~situation()
{
}
int main()
{
cout << "请输入序列长度" << endl;
int n;
cout << "n=";
cin >> n;
situation S(n);
S.init();
S.graphizableCheck();
if (S._isGraphizableCheck)
{
S.Havle();
if (!S.constructSimpleGraph())cout << "无法构建简单图" << endl;
if (S._isConnected())
{
cout << "是连通图" << endl;
if (S.Eular())
{
cout << "是欧拉图" << endl;
cout << "存在欧拉回路";
S.eularCircuit(1);
/*cout << endl;
while (!s.empty())
{
cout << s.top() << " ";
s.pop();
}*/
}
else {
cout << "不是欧拉图" << endl;
}
}
else cout << "不是连通图" << endl;
}
}