• hdu 4786 Fibonacci Tree 生成树


    先黑边优先做一次生成树得到白边的最小值min,再以白边优先做一次生成树得到白边的最大值max,只要min到max之间有Fibonacci数则可以,因为从min到max总可以去掉一条黑边换成一条白边。

    #include <stdio.h>
    #include <string.h>
    #define maxn 110000
    struct edge
    {
        int u,v,flag;
    }e[maxn];
    int fib[120];
    int p[maxn];
    int find(int x)
    {
        if(p[x]==x) return x;
        else return p[x]=find(p[x]);
    }
    void link(int a,int b)
    {
        int x=find(a);
        int y=find(b);
        if(x!=y) p[x]=y;
    }
    int main()
    {
        int i;
        int sum,ans;
        int n,m;
        int u,v,flag;
        int Cas=0;
        int T;
        int Max,Min;
        fib[1]=fib[0]=1;
        for(i=2;i<=30;i++)
            fib[i]=fib[i-1]+fib[i-2];
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            Cas++;
            sum=0;
            for(i=1;i<=m;i++)
                scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].flag);
            for(i=1;i<=n;i++)  p[i]=i;
            for(i=1;i<=m;i++)
            {
                u=e[i].u,v=e[i].v,flag=e[i].flag;
                if(find(u)!=find(v))
                {
                    link(u,v);
                    sum++;
                }
            }
            if(sum<n-1)
            {
                printf("Case #%d: No
    ",Cas);
                continue;
            }
            sum=0;
            for(i=1;i<=n;i++)  p[i]=i;
            for(i=1;i<=m;i++)
            {
                u=e[i].u,v=e[i].v,flag=e[i].flag;
                if(flag==0) continue;
                if(find(u)!=find(v))
                {
                    link(u,v);
                    sum++;
                }
            }
            Max=sum;
            sum=0;
            for(i=1;i<=n;i++)  p[i]=i;
            for(i=1;i<=m;i++)
            {
                u=e[i].u,v=e[i].v,flag=e[i].flag;
                if(flag==1) continue;
                if(find(u)!=find(v))
                {
                    link(u,v);
                    sum++;
                }
            }
            Min=n-1-sum;
            ans=0;
            for(i=0;i<=30;i++)
            {
                if(fib[i]<=Max&&fib[i]>=Min)
                {
                    ans=1;
                    break;
                }
            }
            if(ans==1) printf("Case #%d: Yes
    ",Cas);
            else printf("Case #%d: No
    ",Cas);
        }
        return 0;
    }
    


     

  • 相关阅读:
    多线程 分配
    fopen:文本和二进制方式打开方式对比【转】
    C优先级列表【转】
    sscanf用法
    heap和stack【转】
    大端小端【转】
    二级指针与二维数组的秘密【二者不等】
    C++中的空类编译器默认隐式声明哪些成员函数【CSDN】
    项目内存泄漏问题及解决方案后续
    浅谈部门前台框架中的几个方法<一>
  • 原文地址:https://www.cnblogs.com/vermouth/p/3710144.html
Copyright © 2020-2023  润新知