hdu4786Fibonacci Tree 最小生成树

来源:互联网 发布:天网软件拖欠工资 编辑:程序博客网 时间:2024/06/10 11:06
//给出一个图,图的每一条边可能是白边//也可能是黑边,问能否找到一个生成树//这个生成树中白边的个数是一个fabnaci数//找一个最大生成树和一个最小生成树//在这个范围内有fabnaci数就可以找到#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn = 1e5+10 ;int Fab[maxn] ;struct node{    int u ,v ;    int w ;    bool operator<(const struct node tmp)const    {        return w < tmp.w ;    }}edge[maxn] ;int F[maxn] ;int find(int x){    if(F[x] == -1)return x  ;    return F[x] = find(F[x]) ;}bool join(int x , int y){    int fx = find(x) ;    int fy = find(y) ;    if(fx == fy)return false;    F[fx] = fy ;    return true ;}int main(){    int  n  , m ;    int t ;    int len = 3;    Fab[1] = 1 ;Fab[2] = 2 ;    for(int i = 3;;i++)    if(Fab[i-1] + F[i-2] > maxn)    {        len = i-1 ;        break ;    }    else Fab[i] = Fab[i-1] + Fab[i-2] ;    scanf("%d"  ,&t) ;    int cas = 0 ;    while(t--)    {        scanf("%d%d" , &n , &m) ;        for(int i = 1;i <= m;i++)        scanf("%d%d%d" , &edge[i].u , &edge[i].v,&edge[i].w) ;        sort(edge+1 , edge+1+m) ;        int sum1 = 0 ;        int sum2 = 0 ;        int flag = 0 ;        printf("Case #%d: " , ++cas) ;        memset(F , -1 , sizeof(F)) ;        for(int i = 1;i <= m;i++)        if(join(edge[i].u , edge[i].v))        sum1 += edge[i].w ,flag++ ;        if(flag != n - 1)        {            puts("No")  ;            continue ;        }        memset(F , -1 , sizeof(F)) ;        for(int i = m;i >= 1;i--)        if(join(edge[i].u , edge[i].v))        sum2 += edge[i].w ;        bool ff = false ;        for(int i = 1;i <= len;i++)        if(sum1 <= Fab[i]  && Fab[i] <= sum2)        {            ff = true ;            break ;        }        if(ff)puts("Yes") ;        else puts("No");    }    return  0 ;}

0 0
原创粉丝点击