-
题目链接
http://poj.org/problem?id=1659
-
关于Havel-Hakimi定理
引用一篇非常详细的介绍:https://blog.csdn.net/shuangde800/article/details/7857246
-
关于此题
利用vector <pair<int,int>>结构存储度和结点的编号。根据Havel定理,对vector连续进行排序、删除操作,能够很容易判断出可图性。对于还原图的操作,找出度最大的点v[0],它的度为v[0].first,把它和度次大的v[0].first个点之间连边,然后删去这个点,继续排序,填1,循环这个过程,直到建出完整的图。(还原图的答案不唯一)
-
代码
#include <iostream>
#include <vector>
#include <algorithm>
#define MAX 200
using namespace std;
vector <pair<int,int>> v;
bool cmp(pair<int, int>a,pair<int, int >b)
{
return a.first>b.first;
}
int main()
{
int T;
while (cin>>T)
{
while (T--)
{
int res[MAX][MAX]={0};
int N;
cin>>N;
for (int i=1;i<=N;i++)
{
int a;
cin>>a;
v.push_back(make_pair(a, i));
}
int flag=1;
while (!v.empty())
{
sort(v.begin(),v.end(),cmp);
if (v.size()-1<v[0].first)
{
flag=0;
break;
}
for (int i=1,j=0;i<v.size()&&j<v[0].first;i++,j++)
{
res[v[i].second][v[0].second]=1;
res[v[0].second][v[i].second]=1;
v[i].first--;
}
v.erase(v.begin());
for (int i=1;i<=v.size();i++)
{
if (v[i].first<0)
{
flag=0;
break;
}
}
}
if (flag==1)
{
cout<<"Yes"<<endl;
for (int i=1;i<=N;i++)
{
for (int j=1;j<=N;j++)
{
cout<<res[i][j]<<" ";
}
cout<<endl;
}
}
else
cout<<"No"<<endl;
v.clear();
}
v.clear();
}
v.clear();
}