1. 程式人生 > >Havel-Hakimi定理的方法來構圖

Havel-Hakimi定理的方法來構圖

給定一組非負數字,(數字為節點的度),判斷該組數字能不能構成圖。

Havel-Hakimi定理:

將序列按照從大到小排序之後,從第二個數開始到第一個數的長度+1為止,依次減1。每操作一次,刪掉第一個數字。直到整個陣列被刪完都沒有-1出現。則可圖。

按照這個定理,我們可做的操作如下:

1.排序

2.先判斷第一個數的度是否大於序列-1的長度,如果大於則非圖。       

                                                                         如果小於等於,則後面的數依次減1.小於0,則跳出。

3.存圖:迴圈過程中,如果能減1,則第一個數之後的id都指向第一個數。

例項:

3 1 2 1 1

第一次:3 2 1 1 1           刪掉3,後面依次減1

得:1 0 0 1

第二次:1 1 0 0.刪掉1,後面依次減1

得:0 0 0

所以可圖

程式碼如下:

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using
namespace std; typedef struct { int id; int d; }Arg; Arg arg[10]; int ans[20][20]; int cmp(const void *a,const void *b){ return ((Arg*)b)->d-((Arg*)a)->d; }//從大到小 int main(){ int t,n; cin>>t; while(t--){ cin>>n; memset(ans,0,sizeof
(ans));//每一次,將陣列置0 for(int i=0;i<n;i++){ cin>>arg[i].d; arg[i].id=i; } int k=0,i,j; while(k<n){ qsort(arg+k,n-k,sizeof(arg[0]),cmp);//第一次排序後,每次刪除第一個數排序 if(arg[k].d>n-k-1) break;//如果當前度數已經大於後面的長度,這說明不可能是圖 for(i=1;i<=arg[k].d;i++){//次數 if(arg[i+k].d<=0)//小於0跳出 break; arg[i+k].d--; ans[arg[k].id][arg[k+i].id]=ans[arg[k+i].id][arg[k].id]=1;//將後一個數的id,指向前一個數 } if(i<=arg[k].d)//中途跳出 break; k++; } if(k<n)//沒有刪完,就跳出了 cout<<"NO"<<endl; else { cout<<"YES"<<endl; for(i=0;i<n;i++){ for( j=0;j<n;j++) cout<<ans[i][j]<<" "; cout<<endl; } } } return 0; }