http://www.cnblogs.com/wally/p/3281361.html
poj 1659(havel算法)
题目链接:http://poj.org/problem?id=1659
思路: havel算法的应用:
(1)对序列从大到小进行排序。
(2)设最大的度数为 t ,把最大的度数置0,然后把最大度数后(不包括自己)的 t 个度数分别减1(意思就是把度数最大的点与后几个点进行连接)
(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,能构成图,跳出!
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 #define MAXN 14
7
8 struct Node{
9 int num,id;
10 }pp[MAXN];
11
12 int n;
13 int map[MAXN][MAXN];
14
15 int cmp(const Node &p,const Node &q)
16 {
17 return p.num>q.num;
18 }
19
20 int main()
21 {
22 int _case;
23 scanf("%d",&_case);
24 while(_case--){
25 scanf("%d",&n);
26 for(int i=1;i<=n;i++){
27 scanf("%d",&pp[i].num);
28 pp[i].id=i;
29 }
30 memset(map,0,sizeof(map));
31 bool flag=true;
32 while(true){
33 sort(pp+1,pp+n+1,cmp);
34 if(pp[1].num==0)break;
35 for(int i=1;i<=pp[1].num;i++){
36 pp[1+i].num--;
37 if(pp[1+i].num<0)flag=false;
38 map[pp[1].id][pp[1+i].id]=map[pp[1+i].id][pp[1].id]=1;
39 }
40 pp[1].num=0;
41 if(!flag)break;
42 }
43 if(flag){
44 puts("YES");
45 for(int i=1;i<=n;i++){
46 printf("%d",map[i][1]);
47 for(int j=2;j<=n;j++){
48 printf(" %d",map[i][j]);
49 }
50 printf("
");
51 }
52 }else
53 puts("NO");
54 if(_case)puts("");
55 }
56 return 0;
57 }