题目:
Frogs' Neighborhood
Description 未名湖附近共有N个大小湖泊L1, L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ i ≤ N)。如果湖泊Li和Lj之间有水路相连,则青蛙Fi和Fj互称为邻居。现在已知每只青蛙的邻居数目x1, x2, ..., xn,请你给出每两个湖泊之间的相连关系。 Input 第一行是测试数据的组数T(0 ≤ T ≤ 20)。每组数据包括两行,第一行是整数N(2 < N < 10),第二行是N个整数,x1, x2,..., xn(0 ≤ xi ≤ N)。 Output 对输入的每组测试数据,如果不存在可能的相连关系,输出"NO"。否则输出"YES",并用N×N的矩阵表示湖泊间的相邻关系,即如果湖泊i与湖泊j之间有水路相连,则第i行的第j个数字为1,否则为0。每两个数字之间输出一个空格。如果存在多种可能,只需给出一种符合条件的情形。相邻两组测试数据之间输出一个空行。 Sample Input 3 7 4 3 1 5 4 2 1 6 4 3 1 4 2 0 6 2 3 1 1 2 1 Sample Output YES 0 1 0 1 1 0 1 1 0 0 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 0 1 1 0 1 0 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 NO YES 0 1 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 Source |
[Submit] [Go Back] [Status] [Discuss]
思路:这个是Havel定理的应用,关于Havel定理:Havel-Hakimi定理(判断一个序列是否可图)
首先我们对这个序列进行排序,然后找出最大的度数n,然后在这个排好序的序列中对接下来的n个数进行减一,如果出现两种情况就证明这个序列不可图,否则就就在邻接矩阵中把这两个点连起来
①某次对剩下的序列排序后,最大的度数超过了剩下的顶点数
②对最大的度数后面的n个度数进行减1后,出现了负数
如果出现了这两种情况,那么这个序列不可图
我们用一个结构体来记录一个顶点的度数和这个顶点的标号,具体看代码
代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <set>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define mod 10000007
#define debug() puts("what the fuck!!!")
#define N (1010000)
#define ll long long
using namespace std;
struct node
{
int degree,id;//顶点的度数和标号
} v[20];
int map[20][20];
bool cmp(node a,node b)
{
return a.degree>b.degree;
}
int main()
{
int t,n,flag;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&v[i].degree);
v[i].id=i;//记录顶点的编号
}
mem(map,0);
flag=1;
for(int k=0; k<n; k++)
{
sort(v+k,v+n,cmp);//从第k位开始,对整个数组排序
int i=v[k].id;//当前要连的顶点的编号
int d1=v[k].degree;//记录当前这个节点的度数
if(d1>n-k-1)//当当前节点的度数比剩余的顶点数要大的时候,则不存在相连的关系
flag=0;
for(int r=1; r<=d1&&flag; r++)//从当前点开始给后面的度数减一
{
int j=v[k+r].id;//当前要连的顶点的编号
if(v[k+r].degree<=0)//出现负值代表不存在相连的关系
flag=0;
v[k+r].degree--;
map[i][j]=map[j][i]=1;
}
}
if(flag)
{
puts("YES");
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(j)printf(" ");
printf("%d",map[i][j]);
}
puts("");
}
}
else
puts("NO");
if(t)
puts("");
}
return 0;
}