HDOJ--4786--Fibonacci Tree【生成树】

题意:给出n个点,m条边,和边的信息。边有两种颜色,白色和黑色,现要求构造一个生成树,看能否满足白边的数量是斐波那契数。

这道题比赛的时候,小白想到了一种方法:按边颜色排序后,先用白边优先建树,求出最大白边最大个数maxm,再用黑边优先建树,求出白边最小个数minm,看这两个范围内是否存在斐波那契数。

听上去感觉还挺有道理,但是不知道怎么证明正确性,后来想想,生成树构造完之后,再添加任意一条边都会产生回路,而产生回路之后就有边会被替换,而minm是最少的白边数,也就是minm个白边是不会被换掉的,maxm同理,所以中间的回路替换掉边总能保证用白边替换黑边,或者黑边替换白边,所以可以这么做。

我信心满满的开始敲,然后WA了。。因为我写完cmp函数后忘记写sort了,而且还过了样例。改过之后交一发,还是WA,后来发现数组开了110。。。而且提示是WA不是RE

另外,这道题如果不进行路径压缩,会超时

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 110000
#define eps 1e-7
#define INF 0x7FFFFFFF
#define seed 131
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct node{
    int u,v,col;
}edge[MAXN];
int father[MAXN],fi[90];
int n,m,flag;
bool cmp(node x,node y){
    return x.col>y.col;
}
int find(int x){
    int t = x;
    while(father[t]!=t){
        t = father[t];
    }
    int k = x;
    while(k!=t){
        int temp = father[k];
        father[k] = t;
        k = temp;
    }
    return t;
}
void solve(){
    int i,j=0;
    int flag2 = 0;
    int minm,maxm;
    minm = maxm = 0;
    sort(edge,edge+m,cmp);
    for(i=0;i<m;i++){
        int a = find(edge[i].u);
        int b = find(edge[i].v);
        if(a!=b){
            if(edge[i].col==1)  maxm++;
            father[a] = b;
            j++;
            if(j>=n-1){
                flag2 = 1;
                break;
            }
        }
    }
    if(flag2==0){
        return ;
    }
    for(i=1;i<=n;i++){
        father[i] = i;
    }
    j = 0;
    for(i=m-1;i>=0;i--){
        int a = find(edge[i].u);
        int b = find(edge[i].v);
        if(a!=b){
            if(edge[i].col==1)  minm++;
            father[a] = b;
            j++;
            if(j>=n-1)  break;
        }
    }
    //cout<<minm<<" "<<maxm<<endl;
    for(i=1;i<45;i++){
        if(fi[i]>=minm&&fi[i]<=maxm)
		{
 			 flag = 1;
 			 break;
 		}
    }
}
int main(){
    int i,j,k=1,t;
    int a,b,c;
    fi[1] = 1;
    fi[2] = 2;
    for(i=3;i<45;i++){
        fi[i] = fi[i-1] + fi[i-2];
        //cout<<fi[i]<<" "<<i<<" "<<endl;
    }
    scanf("%d",&t);
    while(t--){
        flag = 0;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)   father[i] = i;
        for(i=0;i<m;i++){
            scanf("%d%d%d",&a,&b,&c);
            edge[i].u = a;
            edge[i].v = b;
            edge[i].col = c;
        }
        solve();
        if(flag)    printf("Case #%d: Yes\n",k++);
        else    printf("Case #%d: No\n",k++);
    }
    return 0;
}

HDOJ--4786--Fibonacci Tree【生成树】

时间: 2024-10-12 01:21:43

HDOJ--4786--Fibonacci Tree【生成树】的相关文章

hdoj 4786 Fibonacci Tree 【生成树+想法】

题目:hdoj 4786 Fibonacci Tree 题意:给出 n 个点 m 条边的图,边只有两种颜色,白色和黑色,让你判断能不能让一个生成树中白边的个数为斐波那契数. 分析:这是个想法题目,前提是知道生成树的定义:生成树必须是所有点都在树中 那么既然要是斐波那契数,我只要把白色边的最大个数和最小个数求出来,如果这个范围内有斐波那契数的话,那么就满足条件. 当然这样求的前提条件是期间的所有的生成树都是满足条件的.即都是满足能够生成树的. ok,AC代码: #include<iostream>

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

HDOJ 4786 Fibonacci Tree

最大生成树夹最小生成树,老题目了,依稀记得当年在成都靠这题捡了个铜..... Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1572    Accepted Submission(s): 479 Problem Description Coach Pang is interested in Fibonac

Hdoj 4786 Fibonacci Tree 【kruskal】

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

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 最小生成树变形

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

HDU--4786 Fibonacci Tree 生成树+贪心?

N个顶点,M条边,每条边可能为黑色或是白色( 0 or 1 ),问有没有可能用为斐波那契数的数目的白色边构成一棵生成树.所以需要删掉图中的环,根据每次删掉的边有一个白色边的上限和下限,判断一下中间有没有斐波那契数就可以了.实现方法是根据颜色排序,先放黑色边得到的是最小数目的白色边构成的生成树,先放白色边得到是最大数目的白色边构成的生成树. #include<cstring> #include<string> #include<fstream> #include<i

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

POJ 4786 Fibonacci Tree

Fibonacci Tree Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 478664-bit integer IO format: %I64d      Java class name: Main Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him to do som

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