這裡首先複習一下什麼叫“簡單圖”(其實是自己忘記了==!).......
一個圖如果不含重邊或環則稱為簡單圖。
1 、Havel 定理:把度排序,從大到小,類似拓撲排序,只是把過程反過來而已。
具體過程:貪心的方法是每次把頂點按度大小從大到小排序,取出度最大的點 Vi,依次和度較大 的那些頂點 Vj 串連,同時減去 Vj 的度。串連完之後就不再考慮 Vi 了,剩下的點再次排 序然後找度最大的去串連……這樣就可以構造出一個可行解。 判斷無解有兩個地方,若某次選出的 Vi 的度比剩下的頂點還多,則無解;若某次 Vj 的度
減成了負數,則無解。
2、 定理 1:總度和 mod 2=0。
3 、定理 2:最大度<=n-1。
#define N 10005int g[11][11];struct node{ int id; int du;}p[11];bool cmp(node a,node b){ return a.du>b.du;}bool gao(int n){ int i,j; for(i=0;i<n;i++){ sort(p+i,p+n,cmp);//對i後面的點度數大到小排序 if(p[i].du<0)return false;//當出現點的度數<0表示不能構成簡單圖 for(j=i+1;j<n && p[i].du>0;j++){//貪心,滿足每個i點的度數,注意i點的度數>0才進行這一步! g[p[i].id][p[j].id] = g[p[j].id][p[i].id] = 1; p[j].du--; p[i].du--; } } return true;}int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); int i,j; for(i=0;i<n;i++){ scanf("%d",&p[i].du); p[i].id = i; } memset(g,0,sizeof(g)); if(gao(n)){ puts("YES"); for(i=0;i<n;i++){ for(j=0;j<n;j++){ if(j)printf(" "); printf("%d",g[i][j]); } puts(""); } } else puts("NO"); if(t)printf("\n"); } return 0;}
HDU 2454更簡單,只需要判斷是否可簡單圖化....