【杂谈】[scoi2005]王室联邦

这题完全没感觉。。。不知道什么情况。。。

照着http://blog.163.com/englanq@126/blog/static/64653471201191645020700/  这位神牛的写法写了一份。。但是加进自己的一些理解就wa了。。。。

交了无数次。。。

很多细节都没搞懂。。。

还有http://hi.baidu.com/kqzxcmh/item/4dfe1be0d37773bb2e140b05 这位神牛的写法只dfs了一次。。很想知道他是怎么做到的


代码中注释掉的地方都是加上就错了但是不明白为什么错了的,求大神指导!!:

    #include<cstdlib> 
    #include<cstring> 
    #include<cmath> 
    #include<cstdio> 
    #include<algorithm> 
    #include<iostream> 
    using namespace std; 
    int n,b; 
    int head[1500+10],l=0; 
    int flag[1500+10]; 
    int size[1500+10]; 
    bool capital[1500+10]; 
    int now; 
    struct E 
    { 
        int v,next; 
    }e[5000+10]; 
    void add(int u,int v) 
    { 
        e[l].v=v; 
        e[l].next=head[u]; 
        head[u]=l++; 
    } 
    void end() 
    { 
        printf("0\n"); 
        exit(0); 
    } 
    struct Te 
    { 
        int mark,pos; 
        bool operator <(const Te &b)const 
        { 
            return mark<b.mark; 
        } 
    }temp[1000+10]; 
    void dfs2(int u,int color,int fa) 
    { 
        flag[u]=color; 
        for(int i=head[u];i!=-1;i=e[i].next) 
        { 
            int v=e[i].v; 
            if(v==fa||flag[v])continue; 
            dfs2(v,color,u); 
        } 
    } 
    void dfs(int u,int fa) 
    { 
        size[u]=1; 
        for(int i=head[u];i!=-1;i=e[i].next) 
        { 
            int v=e[i].v; 
            if(v==fa||size[v])continue; 
            dfs(v,u); 
            size[u]+=size[v]; 
        } 
        if(size[u]<=3*b&&size[u]>=b) 
        { 
            ++now; 
            size[u]=0; 
            dfs2(u,now,fa); 
            capital[u]=true; 
        } 
    } 
    void print() 
    { 
        printf("%d\n",now); 
        printf("%d",flag[1]); 
        for(int i=2;i<=n;i++)printf(" %d",flag[i]); 
        printf("\n"); 
        int tail=1; 
        for(int i=1;i<=n;i++) 
        { 
            if(capital[i]) 
            { 
                temp[tail].mark=flag[i]; 
                temp[tail].pos=i; 
                tail++; 
            } 
        } 
        sort(temp+1,temp+now+1); 
        printf("%d",temp[1].pos); 
        for(int i=2;i<=now;i++)printf(" %d",temp[i].pos); 
        printf("\n"); 
        exit(0); 
    } 
    int main() 
    { 
        memset(head,-1,sizeof(head)); 
        scanf("%d%d",&n,&b); 
        for(int i=1;i<n;i++) 
        { 
            int u,v; 
            scanf("%d%d",&u,&v); 
            add(u,v); 
            add(v,u); 
        } 
        if(b>n)end(); 
        if(n<3*b) 
        { 
          now=1;
          capital[1]=true;
          dfs2(0,1,0); 
          print(); 
        } 
        for(int i=1;i<=n;i++) 
        { 
            memset(flag,0,sizeof(flag)); 
            memset(size,0,sizeof(size)); 
            memset(capital,0,sizeof(capital)); 
            now=0; 
            dfs(i,0); 
            int q=0; 
            for(int j=1;j<=n;j++)if(flag[j])q++; 
            if(q==n)//||size[i]<=b) 
            { 
                //dfs2(i,now,0); 
                print(); 
            } 
        } 
        printf("0\n"); 
        return 0; 
    }  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值