雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

从点的度推出邻接图(贪心解)——pku1659

Posted on 2011-02-20 14:32  huhuuu  阅读(193)  评论(0编辑  收藏  举报
贪心的方法:每次将顶点度数排序,依次将度较大的点的度数减一;
再排序再减……直到某点的度小于0时说明无解输出,或者所有点的度数都为零输出
View Code
#include<iostream>
#include
<stdio.h>
#include
<algorithm>
using namespace std;

struct data
{
int no;
int du;
}p[
20];

bool map[20][20];
bool cmp(data a,data b)
{
if(a.du==b.du)
return a.no<b.no;
return a.du>b.du;
}

int main()
{
int t,n,i,j,temp,k;
scanf(
"%d",&t);
while(t--)
{
scanf(
"%d",&n);
for(i=1;i<=n;i++)
{
scanf(
"%d",&temp);
p[i].no
=i;
p[i].du
=temp;
}

for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
map[i][j]
=0;
}
}
int rt=1;
while(1)
{
sort(
&p[1],&p[n+1],cmp);
for(j=1;j<=p[1].du;j++)
{
if(p[1].du>=n)
{
rt
=0;
break;
}
p[j
+1].du--;
if(p[j+1].du<0)
{
rt
=0;
break;
}
map[p[
1].no][p[j+1].no]=1;
map[p[j
+1].no][p[1].no]=1;
}
p[
1].du=0;

for(k=1;k<=n;k++)//
{
if(p[k].du!=0)
break;
if(p[k].du<0)//度更新后,若有出度小于0退出
{
rt
=0;
break;
}
}

if(rt==0)break;//度更新后,若有出度小于0退出
if(k==n+1)//若度都为零,退出
{
break;
}

}

if(rt==0)
printf(
"NO\n");
else
{
printf(
"YES\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(j==1)
printf(
"%d",map[i][j]);
else
printf(
" %d",map[i][j]);
}
printf(
"\n");
}
}

if(t!=0) printf("\n");
}
}