未名湖附近共有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
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
题解:实际上是给你一个非负整数序列,问是不是一个可图序列,即能不能根据这个序列构造一个图。
其实就是对Havel-Hakimi定理的考察。
用这个序列构造图时有两种不合理情况:
1.每次对剩下的序列排序后,最大的度数(设为d1)超过了剩下的顶点数。
2.对最大度数后面的d1个数各减1后,出现了负数。
本题还要构造得到的图的邻接矩阵:
1.声明一个que结构体,包含顶点和序号两个成员。
2.在每次对剩下的度数递增排序后,设最前面的顶点(即当前度数最大的顶点)序号为i,度数为d1,对后面d1个顶点每个顶点(序号设为j)减1,并连边,即在邻接矩阵mp中设置mp[i][j]=mp[j][i]=1;
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
int x,y;
} que[20];
int cmp(node a,node b)
{
return a.x>b.x;
}
int main()
{
int t,n,f,mp[20][20];
scanf("%d",&t);
while(t--)
{
f=0;
scanf("%d",&n);
memset(mp,0,sizeof(mp));
for(int i=0; i<n; i++)
{
scanf("%d",&que[i].x);
que[i].y=i;
}
for(int i=0; i<n && !f; i++)
{
sort(que+i,que+n,cmp);
if(que[i].x >= n-i) //判断目前最大的度数是否超过剩下的顶点数
f=1;
for(int j=i+1; j<=que[i].x+i; j++)
{
que[j].x--;
if(que[j].x<0) //若出现负数,证明不可图
{
f=1;
break;
}
mp[que[i].y][que[j].y]=mp[que[j].y][que[i].y]=1;
}
}
if(f)
printf("NO\n");
else
{
printf("YES\n");
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(j==0)
printf("%d",mp[i][j]);
else
printf(" %d",mp[i][j]);
}
printf("\n");
}
}
if(t)
printf("\n");
}
return 0;
}