10720 - Graph Construction----------水过了!!

来源:互联网 发布:原单男装 淘宝店铺 编辑:程序博客网 时间:2024/04/29 19:58
 描述: 我们把序列排成不增序,即d1>=d2>=...>=dn,则d可简单图化当且仅当d'=(d2-1, d3-1, ... d(d1+1)-1, d(d1+2), d(d1+3), ... dn)可简单图化。这个定理写起来麻烦,实际上就是说,我们把d排序以后,找出度最大的点(设度为d1),把它和度次大的d1个点之间连边,然后这个点就可以不管了,一直继续这个过程,直到建出完整的图,或出现负度等明显不合理的情况。

举例:序列S7,7,4,3,3,3,2,1  删除序列S的首项 ,对其后的7项每项减1,得到:6,3,2,2,2,1,0,继续删除序列的首项6,对其后的6项每项减1,得到:2,1,1,1,0-1,到这一步出现了负数,因此该序列是不可图的。

  其实仔细想想,就是贪心的构建一个图,一条边对应2个点产生两个度数,每次拿掉一个度数最大的点删掉与之相连的边(有点拓扑排序的意思),与之相连的点度数自然-1;因为要尽可能连成图,当然是让度数大的点度数减少1,否则度数小的点减没了,就不能构成图了;


#include<cstdlib>#include<iostream>#include<cstdio>#include<cmath>#include<set>#include<cstring>#include <algorithm>#define inf 0x7fffffff#define N 10000#define MIN 1e-11#define M 10000#define LL long longusing namespace std;int n,k,h;int a[N];int cmp(const void *a,const void *b){return *(int*)b-*(int*)a;}int main(){#ifndef ONLINE_JUDGE    freopen("ex.in","r",stdin);#endif//    scanf("%d%*c%*c",&t);//    int x=0;    while(scanf("%d",&n)&&n)    {        int num=0;        for(int i=0; i<n; ++i)        {            scanf("%d",&a[i]);            if(a[i])                num++;        }        int maxv,sub,ok=1;        int cnt=0;        while(num)        {            qsort(a,n,sizeof(a[0]),cmp);            num--;            if(a[0]>num)            {                ok=0;                break;            }            int cnt=0;            for(int i=1;a[i]&&i<n&&cnt!=a[0];i++)            {                a[i]--;                if(!a[i])                num--;                cnt++;            }            a[0]=0;        }        printf("%s\n",ok?"Possible":"Not possible");    }    return 0;}


原创粉丝点击