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 }