///贪心,但是测试数据中有n=10的数据,与题目有出入 /* 对于一个给定的度序列,看能不能形成一个简单无向图。 Havel算法的思想简单的说如下: (1)对序列从大到小进行排序。 (2)设最大的度数为t,把最大的度数置0,然后把最大度数后(不包括自己)的t个度数分别减1(意思就是把度数最大的点与后几个点进行连接) (3)如果序列中出现了负数,证明无法构成。如果序列全部变为0,证明能构成,跳出循环.前两点不出现,就跳回第一步! */ #include<stdio.h> #include<string.h> int neib[15][15]; int frog[15],num[15]; int main() { int cas; scanf("%d",&cas); while(cas--) { int n,i,j,yes=1; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&frog[i]); num[i]=i; } memset(neib,0,sizeof(neib)); while(1) { int end=1,max=-1,max_i; for(i=1;i<=n;i++) if(frog[i]!=0) { end=0; break; } if(end) { yes=1; break; } int t=0; for(i=1;i<n;i++) { for(j=n;j>=2;j--) { if(frog[j]>frog[j-1]) { t=frog[j-1]; frog[j-1]=frog[j]; frog[j]=t; t=num[j-1]; num[j-1]=num[j]; num[j]=t; } } } t=0; for(i=1;i<=n;i++) if(frog[i]>0) t++; if(t-1<frog[1]) { yes=0; break; } i=1; while(frog[1]) { if(frog[i]>0&&num[i]!=num[1]&&neib[num[i]][num[1]]==0) { frog[i]--; neib[num[i]][num[1]]=neib[num[1]][num[i]]=1; frog[1]--; } i++; } / /*printf("/n"); for(i=1;i<=n;i++) { for(j=1;j<n;j++) printf("%d ",neib[i][j]); printf("%d/n",neib[i][n]); }*/ // } if(yes) { printf("YES/n"); for(i=1;i<=n;i++) { for(j=1;j<n;j++) printf("%d ",neib[i][j]); printf("%d/n",neib[i][n]); } printf("/n"); } else printf("NO/n/n"); } }