码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 4786 Fibonacci Tree

时间:2014-06-01 16:22:52      阅读:259      评论:0      收藏:0      [点我收藏+]

标签:c   class   blog   code   a   http   

   题目:大致的意思就是说给定n个点和m条边,这m条边分成两种颜色----白色和黑色,问是否能够形成一个生成树使得白色边的个数是一个斐波那契数。

         思路:求出白色边能形成的联通图(非环)的最多边数和最少边数。最大数可以用白边的并查集求得(max=num),而最少边数可以用黑边的并查集求的(min=n-1-num),然后再看在min--max之间是否存在斐波那契数就可以了。

         解释:为什么这样求联通图的白边的个数区间是对的呢?首先上限就不用说了。那么我们想假设这个图能够形成生成树,这颗树里面除了白边就是黑边,看下边这两个图。

         bubuko.com,布布扣bubuko.com,布布扣

那么我们可以看到白边的最大个数是6,黑边也是6,那么白边的范围就是[3,6],怎么实现呢?我们可以看到要想形成生成树,可以在最大白边的基础上去掉一些白边,用黑边来填充,那么这些白边就是4-7,5-7,6-7。这个图看起来有些特殊啊因为同时两边都有4-7,5-7,6-7。

那么白边的图我们换一个

bubuko.com,布布扣bubuko.com,布布扣

此时我们可以看到白边图和黑边图不再存在相同边不同色的边了,那么此时我们可以通过连接黑7和白7构成生成树,当然存在重复点,那么我们就可以去掉黑4-7或4-10,黑5-7或白5-10,黑6-7或白6-10,那么这样就行成了白边[3-6]的区间。

此时,证明完毕。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int t[30];
int f[100010];
int ik;
int n,m;
struct node
{
    int l,r,c;
}c[100010];

void init()
{
    t[1]=1;
    t[2]=2;
    for(ik=3;t[ik-1]<=100000;ik++)
    {
        t[ik]=t[ik-1]+t[ik-2];
    }
}

int look(int x)
{
    if(x!=f[x]) f[x]=look(f[x]);
    return f[x];
}
int solve(int col)
{
    int x,y,num=0;
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=0;i<m;i++)
    if(c[i].c!=col)
    {
        x=look(c[i].l),y=look(c[i].r);
        if(x!=y)
        {
            f[x]=y;
            num++;
        }
        if(num==n-1) return n-1;
    }
    return num;
}

int main()
{
    int tt;
    scanf("%d",&tt);
    int cas=1;
    init();
    while(cas<=tt)
    {
       cin>>n>>m;
       for(int i=0;i<m;i++)
       {
           scanf("%d%d%d",&c[i].l,&c[i].r,&c[i].c);
       }
       printf("Case #%d: ",cas++);
       int num=0;
       num=solve(2);
       if(num!=n-1)
       {
           printf("No\n");
           continue;
       }
       int ma=solve(0);
       int mi=n-1-solve(1);
       bool flag=false;
       for(int i=1;i<ik;i++)
       {
           if(t[i]>=mi&&t[i]<=ma)
           {
               flag=true;
               break;
           }
       }
       if(flag) printf("Yes\n");
       else printf("No\n");
    }
    return 0;
}

hdu 4786 Fibonacci Tree,布布扣,bubuko.com

hdu 4786 Fibonacci Tree

标签:c   class   blog   code   a   http   

原文地址:http://blog.csdn.net/u010650359/article/details/27842059

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!