烂活
方法是先确定点和边范围,这里我让边数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;
}
}