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 }
View Code
原文地址:https://www.cnblogs.com/wally/p/3281361.html