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("\n");

51             }

52         }else

53             puts("NO");

54         if(_case)puts("");

55     }

56     return 0;

57 }
View Code

 

你可能感兴趣的:(poj)