【离散数学】无向欧拉图的判定 (c++)

实验要求:
1.给定一非负整数序列(例如:(4,2,2,2,2))。
2.判断此非负整数序列是否是可图化的,是否是可简单图化的。
3.如果是可简单图化的,根据Havel定理过程求出对应的简单图,并输出此简单图的相邻矩阵(默认第i行对应顶点vi)。
4.判断此简单图是否是连通的。
5.如果是连通图,判断此图是否是欧拉图。如果是欧拉图,请输出一条欧拉回路(输出形式如:v2->v1->v5->v3->v4->v5->v2)。

--------------------------------------------分割线------------------------------------------------

对于整数序列的定义,这里运用了struct来进行运算,方便后续代码实现

struct k
{
   
	int len;//该点的度数
	int num;//该点的编号
	int d;//该点的度数,保存不动,方便运算结束后将度数恢复
}a[10000];

可图化的判断:所有顶点的度数和为偶数。

for (int i = 1; i <= n; i++)
	{
   
		cin >> s;
		int t = s;
		while (s < 0|| s !=t)
		{
   
			cout << "不能输入负数,小数" << endl;
			cin >> s;
		}
		a[i].len = s;
		a[i].num = i;
		a[i].d = a[i].len;
		sum += a[i].len;
	}
	if (sum % 2 != 0)
	{
   
		cout << "该序列不可图化" << endl;
		return 0;
	}

可简单图化判断:Havel定理
Havel定理描述
  给定一个非负整数序列{d1,d2,…dn},若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化。进一步,若图为简单图,则称此序列可简单图化。(顶点的度是指与该顶点相铃的顶点数)

可图化的判定比较简单:d1+d2+…dn=0(mod2)。关于具体图的构造,我们可以简单地把奇数度的点配对,剩下的全部搞成自环。

可简单图化的判定,有一个Havel定理,是说: 我们把序列排成不增序,即d1>=d2>=…>=dn,则d可简单图化当且仅当d’=(d2-1, d3-1, … d(d1+1)-1, d(d1+2), d(d1+3), … dn)可简单图化。
  
原文链接:https://blog.csdn.net/qq_35033987/article/details/78889683)

例如:(4 4 2 2 2 2)可简单图化——>(3 1 1 1 2)可简单图化——>
(3 2 1 1 1)可简单图化——>(1 0 0 1)可简单图化——>(1 1 0 0)可简单图化——>(0 0 0 0)可简单图化
(0 0 0 0)显然可简单图化,故(4 4 2 2 2 2)可简单图化
代码见下:

bool cmp(k x, k y)
{
   
	return x.len > y.len;
}



bool book = 1;//判断是否可简单图化;
int t = n;//t为当前序列元素不为零的个数
for (int i = 1; i <= t; i++)
{
   
	sort(a + i, a + n + 1, cmp);//快排
	if (a[i].len == 0)
		break;
	if (a[i].len > t - i)//若最大元素大于剩余元素个数,即会出现负数
	{
   
		book = 0;
		break;
	}
	for (int j = 1; j <= a[i].len; j++)//模拟Havel
	{
   
		a[i + j].len--;
		c[a[i].num][a[i + j].num] = 1;//c[i][j]=1——>i与j有边
		c[a[i + j].num][a[i].num] = 1;
		if (a[i + j].len == 0)
			t--;
	}
}
if (book == 0)
{
   
	cout << "不可简单图化" << endl;
	return 0;
}
cout << "可简单图化" << endl;

输出简单图相邻矩阵:直接将 c[n][n] 输出

cout << "    " ;
	for (int i = 1; i <= n
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值