实验要求:
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