OUC离散数学II实验一C++ 判断连通图(欧拉回路)

实验主题
可简单图化、连通图、欧拉图和哈密顿图的判断

实验目的
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;
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值