HDU 4786 Fibonacci Tree 最小生成樹

Fibonacci Tree

題目鏈接:

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

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, ... )node

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).c++

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.ide

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 1spa

Sample Output

Case #1: Yes
Case #2: Norest

Hint

題意

給你一個由白邊和黑邊組成的圖,問你能不能找到一個生成樹,使得白邊的個數是Fibonacci數code

題解:

考慮白邊最多狀況的生成樹時候白邊數量爲Max,最少的時候爲Minthree

那麼[Min,Max]這個區間內的白邊數量均可以取到ip

因此求出Min和Max便可ci

坑點:圖不聯通

代碼

#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);
}
相關文章
相關標籤/搜索