• [数据生成器]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
    ", 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
    ", 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
    ",i,j);
    147     }
    148     return 0;
    149 }
    View Code
  • 相关阅读:
    JavaScript脚本学习
    PE文件结构 (转贴)
    Squid 代理服务器 编译源码 伪造HTTP_X_FORWARDED_FOR 请求头
    设置win2003远程桌面允许2个以上会话
    2003远程桌面声音问题
    AS3正则表达式
    Visual Studio技巧之打造拥有自己标识的代码模板
    如何重建sql数据库索引
    多线程系列(转)
    时间差
  • 原文地址:https://www.cnblogs.com/CQBZOIer-zyy/p/3818078.html
Copyright © 2020-2023  润新知