题目链接:http://poj.org/problem?id=1659
题意: 中文题目,不用说了吧。
思路: havel算法的应用:
(1)对序列从大到小进行排序。
(2)设最大的度数为 t ,把最大度数后(不包括自己)的 t 个度数分别减1,然后最大的度数置0(意思就是把度数最大的点与后几个点进行连接)
(3)如果序列中出现了负数,证明无法构成。如果序列全部变为0,证明能构成,跳出循环。前两点不出现,就跳回第一步!
简单例子:
4 4 3 3 2 2
第二步后0 3 2 2 1 2
排完续后3 2 2 2 1 0
第二步后0 1 1 1 1 0
排完续后1 1 1 1 0 0
第二步后0 0 1 1 0 0
排完续后1 1 0 0 0 0
第二步后0 0 0 0 0 0
全为0,能构成图,跳出!
AC代码:
#include<cstdio>
#include<stack>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
int d,id;
}s[15];
int mp[15][15];
bool cmp(node A,node B){
return A.d > B.d;
}
int main() {
int t; scanf("%d",&t);
while(t --){
memset(mp,0,sizeof(mp));
int n; scanf("%d",&n);
for(int i = 1;i <= n;i ++){
scanf("%d",&s[i].d);
s[i].id = i;
}
int flag = 1;
while(1){
sort(s + 1,s + 1 + n,cmp);
if(s[1].d == 0) break;
for(int i = 2;i <= 1 + s[1].d;i ++){
s[i].d --;
if(s[i].d < 0){ flag = 0; break; }
mp[s[1].id][s[i].id] = mp[s[i].id][s[1].id] = 1; //构图, 很明显 无向图是对称矩阵
}
s[1].d = 0;
if(!flag) break;
}
if(!flag) printf("NO\n");
else {
printf("YES\n");
for(int i = 1;i <= n;i ++,printf("\n"))
for(int j = 1;j <= n;j ++)
printf("%d ",mp[i][j]);
}
printf("\n");
}
return 0;
}