POJ 1659 Frogs' Neighborhood

给定一个非负整数列,判断其是否是可图的;

(Havel-Hakimi定理) 由非负整数组成的非增序列s:d1, d2, …, dn(n ≥2, d1 ≥1)
是可图的,当且仅当序列
s1: d2– 1, d3– 1, …, d(d1+1)– 1, d(d1+2), …, dn
是可图的。序列s1中有n-1个非负整数,s序列中d1后的前d1个度数(即d2~d(d1+1))减1后构成s1中的前d1个数;

#include <iostream>
#include  <cstring>
#include <algorithm>

using namespace std;

const int N = 15;

struct vertex{
     int degree;
     int numvertex;
}V[N];


int cmp(const void *a, const void *b)
{
     vertex *aa = (vertex *)a;
     vertex *bb = (vertex *)b;
     return aa->degree < bb->degree;
}
int main()
{
     int i;
     bool flag;
     int Edge[N][N];
     int T;
     int n, d1;
     cin>>T;
     while( T-- )
     {
          cin>>n;
          for(i = 0; i < n; ++i)
          {
               cin>>V[i].degree;
               V[i].numvertex = i;
          }
          memset(Edge, 0, sizeof(Edge));
          flag = true;
          for(int k = 0; k < n && flag; ++k)
          {
               qsort(V + k, n - k, sizeof(vertex), cmp);
               i = V[k].numvertex;
               d1 = V[k].degree;
               if(d1 > n - k - 1)
                    flag = false;
               for(int j = 1; j <= d1 && flag; ++j)
               {
                    int r;
                    r = V[j + k].numvertex;
                    if( V[j + k].degree <= 0 )
                         flag = false;
                    V[ j + k ].degree--;
                    Edge[i][r] = Edge[r][i] = 1;
               }
          }

          if(flag)
          {
               cout<<"YES"<<endl;
               for(int p = 0; p < n; ++p)
               {
                    for(int q = 0; q < n; ++q)
                    {
                         if(q)
                              cout<<" ";
                         cout<<Edge[p][q];

                    }
                    cout<<endl;
               }
          }
          else
               cout<<"NO"<<endl;
          if(T)
               cout<<endl;
     }
    return 0;
}


 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 15
struct vertex
{
     int degree; //顶点的度
     int index; //顶点的序号
}v[N];

int cmp( const void *a, const void *b )
{
     return ((vertex*)b)->degree - ((vertex*)a)->degree;
}

int main( )
{
     int r, k, p, q;  //循环变量
     int i, j;  //顶点序号(用于确定图中边的两个顶点)
     int d1; //对剩下序列排序后第1个顶点(度数最大的顶点)的度数
     int T, n; //测试数据个数,湖泊个数
     int Edge[N][N], flag;  //邻接矩阵,是否存在合理相邻关系的标志
     scanf( "%d", &T );
     while( T-- )
     {
          scanf( "%d", &n );
          for( i=0; i<n; i++ )
          {
               scanf( "%d", &v[i].degree );
               v[i].index = i; //按输入顺序给每个湖泊编号
          }
          memset( Edge, 0, sizeof(Edge) );
          flag = 1;
          for( k=0; k<n&&flag; k++ )
          {
               //对v数组后n-k个元素按非递增顺序排序
               qsort( v+k, n-k, sizeof(vertex), cmp );
               i = v[k].index; //第k个顶点的序号
               d1 = v[k].degree;
               if( d1>n-k-1 )   flag = 0;
               for( r=1; r<=d1&&flag; r++ )
               {
                    j = v[k+r].index; //后边d1个顶点每个顶点的序号
                    if( v[k+r].degree<=0 ) flag = 0;
                    v[k+r].degree--;
                    Edge[i][j] = Edge[j][i] = 1;
               }
          }
          if( flag )
          {
               puts( "YES" );
               for( p=0; p<n; p++ )
               {
                    for( q=0; q<n; q++ )
                    {
                         if(q) printf( " " );
                         printf( "%d", Edge[p][q] );
                    }
                    puts( "" ); //换行
               }
          }
          else puts( "NO" );
          if(T) puts( "" ); //换行
     }
     return 0;
}


 

你可能感兴趣的:(判断是否可图)