给n个点,以及每个点的度,求一个可以满足的图。
额正解那个算法没有细看,感觉差不多的。
简单想想,分析一下样例就可以判断出无解的条件,
将点按度数从大到小排序,从大的开始处理,依次与后面点相连,
如果连到后面点的度数已经是0了,或者到最后一个点了这个点还没有连完则无解。
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<iostream>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
struct node
{
int w,id;
}s[15];
int vis[15][15];
bool cmp(node a,node b)
{
return a.w>b.w;
}
int main()
{
int T,p,i,j,n,cnt,flag;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
cnt=0;
for(i=0;i<n;i++)
{
scanf("%d",&s[i].w);
s[i].id=i;
cnt+=s[i].w;
}
if(cnt&1)
{
printf("NO\n");
continue;
}
memset(vis,0,sizeof vis);
flag=1;
while(1)
{
sort(s,s+n,cmp);
if(s[0].w==0) break;
cnt=0;i=1;
while(1)
{
if(i==n)
{
flag=0;
break;
}
if(vis[s[i].id][s[0].id])
{
i++;
continue;
}
if(s[i].w==0)
{
flag=0;
break;
}
vis[s[i].id][s[0].id]=vis[s[0].id][s[i].id]=1;
s[i].w--;
cnt++;
if(cnt==s[0].w) break;
i++;
}
if(!flag) break;
s[0].w=0;
}
if(!flag)
printf("NO\n");
else
{
printf("YES\n");
for(i=0;i<n;i++)
{
for(j=0;j<n-1;j++)
printf("%d ",vis[i][j]);
printf("%d\n",vis[i][j]);
}
}
if(T) puts("");
}
return 0;
}