Havel-Hakimi定理的方法來構圖
阿新 • • 發佈:2018-11-10
給定一組非負數字,(數字為節點的度),判斷該組數字能不能構成圖。
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> usingnamespace 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; }