题目大意:
给出一个无向图的顶点度序列{dn},要求判断能否构造出一个简单无向图。若能构造任意一个输出邻接矩阵。
分析:
今年哈尔滨赛区也出了一个一样的题目,而且只要求判定不需要构造。当时我们是用贪心做的,只是到最后也不知道为什么是正确的……
贪心的方法是每次把顶点按度大小从大到小排序,取出度最大的点Vi,依次和度较大的那些顶点Vj连接,同时减去Vj的度。连接完之后就不再考虑Vi了,剩下的点再次排序然后找度最大的去连接……这样就可以构造出一个可行解。
判断无解有两个地方,若某次选出的Vi的度比剩下的顶点还多,则无解;若某次Vj的度减成了负数,则无解。
至于什么是Havel定理,上面这个构造过程就是了^^
详细可以参考这里http://roba.yo2.cn/archives/439802
- /*
- PKU1659 Frogs' Neighborhood
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #define clr(a) memset(a,0,sizeof(a))
- #define N 15
- int d[N],idx[N];
- int cmp(const void *a,const void *b){
- return d[*(int*)b] - d[*(int*)a];
- }
- int main()
- {
- int i,j,k,r,n,T;
- int a[N][N],flag;
- scanf("%d",&T);
- while(T--){
- scanf("%d",&n);
- for(i=0;i<n;i++){ scanf("%d",&d[i]); idx[i]=i; }
- clr(a);
- flag=1;
- //work
- for(k=0;k<n&&flag;k++){
- qsort(idx+k,n-k,sizeof(int),cmp);
- i=idx[k];
- if(d[i]>n-k-1) flag=0;
- for(r=1;r<=d[i]&&flag;r++){
- j=idx[k+r];
- if(d[j]<=0) flag=0;
- d[j]--;
- a[i][j]=a[j][i]=1;
- }
- }
- //output
- if(flag){
- puts("YES");
- for(i=0;i<n;i++){
- for(j=0;j<n;j++){
- if(j) printf(" ");
- printf("%d",a[i][j]);
- }
- puts("");
- }
- }
- else puts("NO");
- if(T) puts("");
- }
- return 0;
- }