离散数学实践试验报告格式.docx
《离散数学实践试验报告格式.docx》由会员分享,可在线阅读,更多相关《离散数学实践试验报告格式.docx(19页珍藏版)》请在冰豆网上搜索。
![离散数学实践试验报告格式.docx](https://file1.bdocx.com/fileroot1/2022-10/10/2d285a21-9f28-4724-bd07-c2d51f37c1fa/2d285a21-9f28-4724-bd07-c2d51f37c1fa1.gif)
离散数学实践试验报告格式
《离散数学应用实践》
实验报告
课序号:
03
学号:
姓名:
任课教师:
陈瑜
评阅成绩:
评阅意见:
提交报告时间:
2014年1月3日
判断图的强连通,单连通,弱连通,判断树,求强分图
(一)问题描述
(二)算法分析
(三)程序源代码
(四)测试数据与运行结果
(五)算法复杂性分析与讨论
(1)问题描述
编写一个程序,从控制台输入一个用邻接矩阵表示的图,程序实现判断该图的强连通性,弱连通性,单连通性,判断该图是否为树,求强分图等操作,并从控制台输出判断结果。
(2)算法分析
程序流程图:
输入操作类型
输入邻接矩阵
求可达矩阵
判断是否为树
判断强连通性
判断单连通性
求基图
求强分图矩阵
判断弱连通性
求强分图
输出结果
1.判断图的强连通性
运用warshall算法先求其可达矩阵,判断可达矩阵元素是否全为一,全为一则具有强连通性;否则不具有。
2.判断图的单连通性
运用warshall算法先求其可达矩阵,判断可达矩阵元素与其对角元素是否全为零,全为零则不具有单连通性;否则具有。
3.判断图的弱连通性
先求其基图,若可达矩阵元素与其对角元素有一个为一,则将其都置一,同时将其可达矩阵主对角线元素全置一,从而得到其基图。
然后再运用warshall算法求其可达矩阵,判断其强连通性,若其基图具有强连通性,则此图具有弱连通性;否则不具有。
4.判断图是否为树
此部分是对于无向图进行判断,先判断此图的强连通性,若不具有强连通性,则不是树;若具有强连通性,再统计其节点总度数,求其边数,如果边数等于顶点数减一,则为树,否则不为树。
5.求图的强分图
同样,先运用warshall算法先求其可达矩阵,然后对其可达矩阵求其转置,与其转置中的对应元素进行“&&”处理,并置主对角元素为一,得到其强分图矩阵。
下面是求强分图的伪码:
While(i{
Flag=ture;//判断强分图标记
While(flag)
{
J=i+l;//扩大强分图范围
判断以i为为强分图新矩阵的左上顶点,逐步扩大强分图矩阵,如果其强分图矩阵全为一,flag置一,否则置零。
}
输出强分图;
I=j;
}
(3)程序源代码
#include
usingnamespacestd;
classmap
{
int**m;
intnum;
public:
map();
voidSetmap(intn);//设置邻接矩阵
voidchange1();//求可达矩阵
voidchange2();//求强分图矩阵
boolIsStrongConnectivity();//判断强连通性
boolIsSingleConnectivity();//判断单连通性
boolIsWeakConnectivity();//判断弱连通性
voidStronggraph();//求强分图
boolIsTree();//判断是否为树
voidshow();//显示矩阵
};
map:
:
map()
{
num=0;
m=NULL;
}
voidmap:
:
Setmap(intn)//设置矩阵
{
num=n;
m=newint*[num];
cout<<"";
for(inth=0;h{
m[h]=newint[num];
cout<<"v"<}
cout<intk;
for(inti=0;i{
cout<<"v"<
for(intj=0;j{
cin>>k;
m[i][j]=k;
}
}
}
voidmap:
:
change1()//求可达矩阵,运用Warshall算法
{
inti,j,k;
for(i=0;i{
for(j=0;j{
if(m[j][i]==1)
{
for(k=0;k{
m[j][k]=m[j][k]||m[i][k];
}
}
}
}
}
voidmap:
:
change2()//求强分图矩阵
{
inti,j;
int**m1;
m1=newint*[num];
for(i=0;i{
m1[i]=newint[num];
}
for(i=0;i{
for(j=0;j{
m1[i][j]=m[j][i];
}
}
for(i=0;i{
for(j=0;j{
m[i][j]=m[i][j]&&m1[i][j];
}
m[i][i]=1;//主对角线置1
}
}
boolmap:
:
IsTree()//判断树
{
intsum=0;
for(inti=0;i{
for(intj=0;j{
if(m[i][j]==1)
{
sum++;
}
}
}
if(!
IsStrongConnectivity())
{
cout<<"不是强连通"<returnfalse;
}
else
{
if(sum/2!
=num-1)//在图为强连通的情况下判断图的边数是否等于顶点数减一
{
returnfalse;//等于则为树,否则不为树
}
}
returntrue;
}
boolmap:
:
IsStrongConnectivity()//判断强连通
{
change1();
for(inti=0;i{
for(intj=0;j{
if(m[i][j]==0)//可达矩阵全为一
{
returnfalse;
}
}
}
returntrue;
}
boolmap:
:
IsSingleConnectivity()//判断单向连通
{
change1();
for(inti=0;i{
m[i][i]=1;
for(intj=0;j{
if((m[i][j]||m[j][i])==0)//两点间相互都不能达到则不为单向连通
{
returnfalse;
}
}
}
returntrue;
}
boolmap:
:
IsWeakConnectivity()//判断弱连通
{
inti,j;
for(i=0;i{
for(j=0;j{
if(m[i][j]||m[j][i]==1)
{
m[i][j]=m[j][i]=1;//先将其变为其基图
}
}
m[i][i]=1;
}
change1();
for(i=0;i{
for(j=0;j{
if(m[i][j]==0)
{
returnfalse;
}
}
}
returntrue;
}
voidmap:
:
Stronggraph()//求强分图
{
change1();
change2();//得到其强分矩阵
intq,p,k,j=0,i=0,l;
while(i{
l=0;//扩大强分图范围变量
if(m[i][i]==1)
{
boolflag=true;
while(flag)
{
j=i+l;//以对角线为1的点为强分图新矩阵的左上顶点,逐步扩大强分图矩阵的
for(k=i;k<=j&&j{
for(p=i;p<=j;p++)
{
if(m[k][p]==0)
{
flag=false;
}
}
}
if(j==num)
{
flag=false;
}
l++;
}
cout<<"强分图为:
"<for(q=i;q{
cout<<"v"<}
cout<i=j;
}
else
{
i++;
}
}
}
voidmap:
:
show()
{
for(inti=0;i{
for(intj=0;j{
cout<}
cout<}
}
voidmain(void)
{
intnum;
mapobj;
intselect=0;
while(select!
=6)
{
cout<cout<cout<cout<cout<cout<cout<";
cin>>select;//输入选择
while(cin.get()!
='\n');//忽略用户输入的其他字符
switch(select)
{
case1:
cout<<"输入元素个数:
"<cin>>num;
obj.Setmap(num);
if(obj.IsStrongConnectivity())
{
cout<<"是强连通图"<}
else
{
cout<<"不是强连通"<}
break;
case2:
c