Frogs' Neighborhood
Time Limit: 5000MS | Memory Limit: 10000K | |||
Total Submissions: 9284 | Accepted: 3912 | Special Judge |
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
POJ Monthly--2004.05.15 Alcyone@pku
解题思路:
Havel-Hakimi定理然后加边输出。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 15
int edge[MAXN][MAXN];
struct Node
{
int no;//序号
int va;//度
};
Node node[MAXN];
int cmp(Node a, Node b)
{
return a.va>b.va;
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(edge,0,sizeof(edge));
int n,i,j,x,y;
cin>>n;
for(i=0; i<n; ++i)
{
cin>>node[i].va;
node[i].no=i;
}
bool flag=true;//判断是否满足Havel-Hakimi定理
for(i=0; i<n&&flag; ++i)//Havel-Hakimi定理
{
sort(node,node+n,cmp);//降序排列
x=node[i].no;//当前首个数
if(node[i].va>n-i-1) flag=false;//个数不够
for(j=1; j<=node[i].va&&flag; ++j)
{
y=node[i+j].no;
if(node[i+j].va<=0) flag=false;//顶点为负度数
--node[i+j].va;
edge[x][y]=edge[y][x]=1;//加边
}
}
if(flag)
{
puts("YES");
for(i=0; i<n; ++i)
{
for(j=0; j<n; ++j)
cout<<edge[i][j]<<" ";
cout<<endl;
}
cout<<endl;//注意每组数之间有空行的格式要求
}
else puts("NO\n");
}
return 0;
}