hdu 4786 Fibonacci Tree

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

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

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

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

那么白边的图我们换一个

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDY1MDM1OQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">

此时我们能够看到白边图和黑边图不再存在同样边不同色的边了。那么此时我们能够通过连接黑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;
}
时间: 2024-08-10 02:11:08

hdu 4786 Fibonacci Tree的相关文章

HDU 4786 Fibonacci Tree 最小生成树变形

思路: 这题比赛的时候想了好久,最后队友机智的想到了. 不过那时不是我敲的,现在敲的1A. 想好就容易了. 直接把1或者0当做边的权值,然后按边从小到大排序,然后算最小生成用到了几条白边,然后再按边从大到小排序,然后再算白边用了几条.然后最小和最大需要用到的白边都算出来了.如果在这最小最大区间中存在那个啥数列的话就是Yes,否则就是No. 为什么在这区间里面就是对的呢?刚开始我也想了好久,然后发现,因为白边权值是1,然后黑边是0,然后假设用到白边最小的是6,最大的是10,那么,我们可以用黑边去替

HDU 4786 Fibonacci Tree(生成树,YY乱搞)

http://acm.hdu.edu.cn/showproblem.php?pid=4786 Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1733    Accepted Submission(s): 543 Problem Description Coach Pang is interested in

HDU 4786 Fibonacci Tree 并查集+生成树=kruskal

Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2149    Accepted Submission(s): 682 Problem Description Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him t

hdu 4786 Fibonacci Tree(最小生成树)

Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2952    Accepted Submission(s): 947 Problem Description Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him t

hdu 4786 Fibonacci Tree ( 最小生成树 )

Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2487    Accepted Submission(s): 796 Problem Description Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him t

HDU 4786 Fibonacci Tree 生成树

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4786 题意:有N个节点(1 <= N <= 10^5),M条边(0 <= M <= 10^5).当中一部分边被染成了黑色,剩下的边是白色,问能不能建立一棵树,树中有斐波那契数个白色边. 思路:用克鲁斯卡尔建三次树,第一是用全部边建树.推断能否建成一棵树,第二次用黑边建树,最多能够用到x条黑边(不成环),n-1-x就是最少须要用的白边的数量,第三次用白边建树,最多能够用到y条白边.假设在[y

hdu 4786 Fibonacci Tree (最小生成树扩展)

///白边优先和黑边优先做两次最小生成树 ///若有斐波那契树在这中间为yes # include <stdio.h> # include <algorithm> # include <iostream> # include <string.h> # include <math.h> using namespace std; struct node { int x; int y; int v; }; struct node a[100010];

HDU 4786 Fibonacci Tree (2013成都1006题) 最小生成树+斐波那契

题意:问生成树里能不能有符合菲波那切数的白边数量 思路:白边 黑边各优先排序求最小生成树,并统计白边在两种情况下数目,最后判断这个区间就可以.注意最初不连通就不行. 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include<cmath> 5 #define LL long long 6 using namespace std; 7 int t,n,m; 8 int

hdu 4786 Fibonacci Tree (最小、最大生成树)

题意: N个点,M条边.每条边连接两个点u,v,且有一个权值c,c非零即一. 问能否将N个点形成一个生成树,并且这棵树的边权值和是一个fibonacii数. (fibonacii数=1,2,3,5,8 .... ) 思路: 若可以生成一棵树.则有最小生成树和最大生成树.假设已经生成了最小MST  P 和最大MST  Q. 将P更换一条边可以得到另一棵生成树,边权和不是和P相等就是比P的边权和大1.(因为边值非零即一).同理搞下去....一定可以得到Q. 所以P的边权和到Q的边权和之间的所有值都能