HDU 4786 Fibonacci Tree 最小生成树

Fibonacci Tree

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=4786

Description

 Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him to do some research on Spanning Tree. So Coach Pang decides to solve the following problem:
  Consider a bidirectional graph G with N vertices and M edges. All edges are painted into either white or black. Can we find a Spanning Tree with some positive Fibonacci number of white edges?
(Fibonacci number is defined as 1, 2, 3, 5, 8, … )

Input

  The first line of the input contains an integer T, the number of test cases.
  For each test case, the first line contains two integers N(1 <= N <= 105) and M(0 <= M <= 105).
  Then M lines follow, each contains three integers u, v (1 <= u,v <= N, u<> v) and c (0 <= c <= 1), indicating an edge between u and v with a color c (1 for white and 0 for black).

Output

  For each test case, output a line “Case #x: s”. x is the case number and s is either “Yes” or “No” (without quotes) representing the answer to the problem.

Sample Input

2
4 4
1 2 1
2 3 1
3 4 1
1 4 0
5 6
1 2 1
1 3 1
1 4 1
1 5 1
3 5 1
4 2 1

Sample Output

Case #1: Yes
Case #2: No

Hint

题意

给你一个由白边和黑边组成的图,问你能不能找到一个生成树,使得白边的个数是Fibonacci数

题解:

考虑白边最多情况的生成树时候白边数量为Max,最少的时候为Min

那么[Min,Max]这个区间内的白边数量都可以取到

所以求出Min和Max即可

坑点:图不联通

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+7;
struct node{
    int x,y,z;
}p[maxn];
bool cmp1(node A,node B){
    return A.z<B.z;
}
bool cmp2(node A,node B){
    return A.z>B.z;
}
int fa[maxn];
int fi(int x){
    return x==fa[x]?x:fa[x]=fi(fa[x]);
}
void uni(int x,int y){
    x=fi(x),y=fi(y);
    if(x==y)return;
    else fa[x]=fa[y];
}
void solve(int Cas){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        fa[i]=i;
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z);
    sort(p+1,p+1+m,cmp1);
    int x1=0,x2=0;
    int D = 0;
    for(int i=1;i<=m;i++){
        if(fi(p[i].x)!=fi(p[i].y)){
            x1+=p[i].z;
            uni(p[i].x,p[i].y);
            D = D + 1;
        }
    }
    if(D!=n-1){
        printf("Case #%d: No\n",Cas);
        return;
    }
    for(int i=1;i<=n;i++)
        fa[i]=i;
    sort(p+1,p+1+m,cmp2);
    for(int i=1;i<=m;i++){
        if(fi(p[i].x)!=fi(p[i].y)){
            x2+=p[i].z;
            uni(p[i].x,p[i].y);
        }
    }
    long long a=1,b=1;
    int flag = 0;
    while(a<=x2||b<=x2){
        if(a>=x1&&a<=x2)
            flag=1;
        if(b>=x1&&b<=x2)
            flag=1;
        a=a+b;
        if(a>b)swap(a,b);
    }
    if(a>=x1&&a<=x2)
        flag=1;
    if(b>=x1&&b<=x2)
        flag=1;
    if(flag)printf("Case #%d: Yes\n",Cas);
    else printf("Case #%d: No\n",Cas);
}
int main(){
    int t;
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++)solve(cas);
}
    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/7151115.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞