havel定理:判断度数序列是否可图(简单图)
题意
未名湖附近共有N个大小湖泊L1, L2, …, Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤i ≤ N)。如果湖泊Li和Lj之间有水路相连(无向图),则青蛙Fi和Fj互称为邻居。现在已知每只青蛙的邻居数目x1,x2, …, xn,请你给出每两个湖泊之间的相连关系。
思路
直接贪心是有误的:1 2 3 2 0
用 havel定理
判定过程:
(1)对当前数列排序,使其呈递减,
(2)从S【2】开始对其后S【1】个数字-1,
(3) 一直循环直到当前序列出现负数(即不是可图的情况)或者当前序列全为0 (可图)时退出。
代码
/*
* Author : Echo
* Email : 1666424499@qq.com
* Description :
* Created Time : 2017/10/15 16:40:58
* Last Modify : 2017/10/15 17:33:16
* File Name : write.cpp
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
using namespace std;
const int maxn=20;
const int maxm=1e4+100;
const int INF=1e9;
int n;
struct node{
int cnt,id;
}an[maxn];
int mp[maxn][maxn];
bool cmp(node a,node b){
return a.cnt>b.cnt;
}
int main(){
int t;
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",&an[i].cnt);
an[i].id=i;
}
memset(mp,0,sizeof(mp));
int flg=1;
while(1){
sort(an+1,an+n+1,cmp);
if(an[1].cnt==0)break;
for(int i=2;i<=n;i++){
if(an[1].cnt==0)break;
an[1].cnt--;
an[i].cnt--;
mp[an[1].id][an[i].id]=mp[an[i].id][an[1].id]=1;
if(an[i].cnt<0){
flg=0;
break;
}
}
if(flg==0)break;
}
if(flg==0){
printf("NO\n\n");
continue;
}
printf("YES\n");
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%d%c",mp[i][j],j==n? '\n':' ');
}
}
printf("\n");
}
return 0;
}