随机生成无向无权连通图

烂活

方法是先确定点和边范围,这里我让边数E∈[V/2*3,V(V-1)/2*3)。因为我纯粹是不喜欢树或太小的图。

然后随机选取起点、终点进行建边,直到边数达到预定边数。

另外,如果图不连通则重新生成。这里我用的FloydWarshall来判断。

还不会并查集,欢迎优化。

目标登场:

int Gr[200][200];

连通性

bool cne__(int siz)
{
	int cG[siz][siz];
	for(int A=0;A<siz;A++)
	{
		for(int B=0;B<siz;B++)
		{
			cG[A][B]=Gr[A][B];//先把图拷贝
		}
	}
	for(int K=0;K<siz;K++)
	{
		for(int I=0;I<siz;I++)
		{
			for(int J=0;J<siz;J++)
			{
				if(cG[I][K]==1 && cG[K][J]==1)
				{
					cG[I][J]=1;
				}
			}
		}
	}
	for(int A=0;A<siz;A++)
	{
		for(int B=0;B<siz;B++)
		{
			if(A!=B && cG[A][B]!=1)
			{
				return false;
			}
		}
	}
	return true;
}

生成

void cret___G(int a,int b)
{
	memset(Gr,0,sizeof(Gr));
	int siz=rand()%(b-a+1)+a;
	Grsiz=siz;//存储图大小
    int c,d;
	c=siz/2*3;
	d=siz*(siz-1)/3*2;
    //自调
	int en=rand()%(d-c+1)+c;//边数
	int sta,end;
	for(int A=0;A<en;A++)
	{
		sta=rand()%siz;
		end=rand()%siz;
		if(sta==end)
		{
			A--;
			continue;
		}
		if(Gr[sta][end]==1)
		{
			A--;
			continue;
		}
		Gr[sta][end]=1;
		Gr[end][sta]=1;
	}
	if(!cne__(siz))
	{
		cret___G(a,b);//再来
	}            
}

总流程

#include<bits/stdc++.h>
/*RCG*/using namespace std;
int Gr[200][200];
int Grsiz;
bool cne__(int siz)
{
	int cG[siz][siz];
	for(int A=0;A<siz;A++)
	{
		for(int B=0;B<siz;B++)
		{
			cG[A][B]=Gr[A][B];
		}
	}
	for(int K=0;K<siz;K++)
	{
		for(int I=0;I<siz;I++)
		{
			for(int J=0;J<siz;J++)
			{
				if(cG[I][K]==1 && cG[K][J]==1)
				{
					cG[I][J]=1;
				}
			}
		}
	}
	for(int A=0;A<siz;A++)
	{
		for(int B=0;B<siz;B++)
		{
			if(A!=B && cG[A][B]!=1)
			{
				return false;
			}
		}
	}
	return true;
}
void cret___G(int a,int b)
{
	memset(Gr,0,sizeof(Gr));
	
	int siz=rand()%(b-a+1)+a;
	Grsiz=siz;
	int c,d;
	c=siz/2*3;
	d=siz*(siz-1)/3*2;
	int en=rand()%(d-c+1)+c;
	int sta,end;
	for(int A=0;A<en;A++)
	{
		sta=rand()%siz;
		end=rand()%siz;
		if(sta==end)
		{
			A--;
			continue;
		}
		if(Gr[sta][end]==1)
		{
			A--;
			continue;
		}
		Gr[sta][end]=1;
		Gr[end][sta]=1;
	}
	if(!cne__(siz))
	{
		cret___G(a,b);
	}            
}
int main()
{
	srand(time(0));
	int minsiz,maxsiz;
	cin>>minsiz>>maxsiz;
	cret___G(minsiz,maxsiz);
	for(int A=0;A<Grsiz;A++)
	{
		for(int B=0;B<Grsiz;B++)
		{
			cout<<Gr[A][B]<<" ";
		}
		cout<<endl;
	}
}

欢迎优化

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值