[数据生成器]UVA10054 The Necklace

应吴老师之邀,写了个数据生成器。

目前这个数据生成器可以保证生成的数据都是合法的,且效率也还不错。只是在建立普通连通图的时候zyy偷懒了,直接把所有点串起来从而保证图的连通。如果有大神有更好的方法请不吝指教,zyy不胜感谢~~

 

下面是代码:

  1 #include<cstdio>
  2 #include<ctime>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<vector>
  7 using namespace std;
  8 #define MAXN 40
  9 #define MAXM 100
 10 
 11 int A[MAXN+10][MAXN+10];
 12 int d[MAXN+10];
 13 
 14 int n, m;
 15 
 16 int GetRand(int L, int R)
 17 {
 18     int Len = R - L + 1;
 19     int Ret = rand() * rand() % Len + L;
 20     return Ret;
 21 }
 22 
 23 inline void Addedge(int u,int v,int o)
 24 {
 25     A[u][v]+=o;A[v][u]+=o;
 26     d[u]+=o;d[v]+=o;
 27     m+=o;
 28 }
 29 
 30 void gen()
 31 {
 32     int i, j, k, t;
 33     bool Again;
 34     memset(A, 0, sizeof(A));
 35     memset(d, 0, sizeof(d));
 36     for(i=1;i<n;i++)//保证图的连通
 37     {
 38         A[i][i+1]++;A[i+1][i]++;
 39         d[i]++;d[i+1]++;
 40     }
 41     for(i=1;i<=m-n+1;i++)//剩下的边随机连接
 42     {
 43         do{
 44             j=GetRand(1,n);
 45             k=GetRand(1,n);
 46             if(j==k) continue;
 47             A[j][k]++;A[k][j]++;
 48             d[j]++;d[k]++;
 49             break;
 50         }while(true);
 51     }
 52     //调整边,使所有的顶点的度为偶数
 53     for(i=1;i<=n;i++)
 54     {
 55         if(d[i]%2)//如果i点度为奇数,就再找一个度为奇数的点
 56         {
 57             for(j=i+1;j<=n;j++)
 58             {
 59                 if(d[j]%2)
 60                 {
 61                     if(A[i][j])//i、j之间有边
 62                     {
 63                         if(d[i]!=1&&d[j]!=1)//i、j之间不止一条边,则删掉一条边
 64                         {
 65                             Addedge(i,j,-1);
 66                             break;
 67                         }
 68                         else
 69                         {
 70                             continue;
 71                         }
 72                     }
 73                     else//i、j之间没有边,则连接i、j
 74                     {
 75                         Addedge(i,j,1);
 76                         break;
 77                     }
 78                 }
 79             }
 80             if(j>n)
 81             {
 82                 for(k=i+1;k<=n;k++)
 83                 {
 84                     if(d[k])
 85                         break;
 86                 }
 87                 t=k;//找一个度为奇数的顶点t
 88                 for(k=1;k<i;k++)//再找一个度为偶数的顶点k,若k与i、t不相连,则连接tk、ik
 89                 {
 90                     if(!A[t][k]&&!A[k][i])
 91                     {
 92                         Addedge(t,k,1);
 93                         Addedge(i,k,1);
 94                         break;
 95                     }
 96                 }
 97                 Again=false;
 98                 if(k>=i)//需要重新调整
 99                 {
100                     for(t=1;t<=n;t++)//连接i与任意一个不相连的顶点t
101                     {
102                         if(!A[t][i]&&i!=t)
103                         {
104                             Addedge(t,i,1);
105                             Again=true;
106                             break;
107                         }
108                     }
109                     if(t>n)//如果找不到这样的t,在确保图的连通的条件下删掉一条边
110                     {
111                         for(t=1;t<=n;t++)
112                         {
113                             if(d[t]>1)
114                             {
115                                 Addedge(t,i,-1);
116                                 Again=true;
117                                 break;
118                             }
119                         }
120                     }
121                 }
122                 if(Again)
123                     i=0;
124             }
125         }
126     }
127 }
128 
129 
130 int main()
131 {
132     //freopen("data4.in","w",stdout);
133     srand(time(NULL));
134     int cas =10000;//GetRand(1, 1);
135     int i,j;
136     printf("%d\n", cas);
137     while(cas-- > 0)
138     {
139         n = GetRand(MAXN/5*3, MAXN);
140         m = GetRand(MAXM/5*3, MAXM);
141         gen();
142         printf("%d\n", m);
143         for(i=1;i<n;i++)
144             for(j=i+1;j<=n;j++)
145                 while(A[i][j]-->0)
146                    printf("%d %d\n",i,j);
147     }
148     return 0;
149 }
View Code

 

posted @ 2014-07-01 12:06  zyy是一只超级大沙茶  阅读(379)  评论(0编辑  收藏  举报