POJ 1658 Frogs' Neighborhood

来源:互联网 发布:刘吉桦陈铭 知乎 编辑:程序博客网 时间:2024/04/19 14:38
第一行是测试数据的组数T(0 ≤ T ≤ 20)。每组数据包括两行,第一行是整数N(2 < N < 10),第二行是N个整数,x1, x2,..., xn(0 ≤ xi ≤ N)。实际上市给定一个非负整数序列,问你是不是一个可图的序列根据Havel-Hakimi定理
1、某次对剩下序列排序后,最大的度数(d1)超过了剩下的顶点数 
2、对最大的度数后面的d1个度数各减1后,出现了负数一旦出现以上两种情形,则可判定该序列是不可图的
本体实现思路:
1:为了确保顶点序号与输入时保持度数顺序一致,特意声明一个vertex结构体,包含了顶点的度和序号两个成员 
2:每次对剩下的顶点按度数从大到小顺序排序后,设最前面的顶点(及当前度数最大的顶点)序号为i、度数为d1,对后面d1个顶点每个顶点(序号设为j)度数减1,并连边,即在邻接矩阵Edge中设置Edge[i][j]和
Edge【i】【j】为1. 

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <vector>#include <map>#include <queue>#include <climits>#include <stack>#include <algorithm>#define long long ll#define M   200using namespace std;#define N 15struct 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 i, r, j;     int d1;                 //对剩下的序列排序后 第一个(度数最大的顶点)的度数     int T, n;                      //case  湖泊个数    int Edge[N][N], flag;           //邻接矩阵,是否存在合理相邻关系的标志    scanf ("%d", &T);    while (T--)    {          scanf ("%d", &n);          for (int i = 0; i < n; i++)          {              scanf ("%d", &v[i].degree);              v[i].index = i;           }                     memset (Edge, 0, sizeof(Edge));          flag = 1;          for (int k = 0; k <= n && flag; k++)          {              //对v数组后n-k个元素按非递增顺序排序              qsort (v+k, v-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];               }           }                  if ( flag )         {            printf("YES");            for (int p =0; p < n; p++)            {               for (int q = 0; q < n; q++)               {                  if (q) printf ( " " );                  printf("%d", Edge[p][q]);                }            }           printf("\n");           }          else put ("NO");         if (T) put ( " ");          }     return 0; }