• LA 6540 Fibonacci Tree


    题意:

    给出一个(n)个点(m)条边的无向图,每条边的颜色为黑色或者白色。问是否存在一颗生成树使得树上白边的数量为斐波那契数。

    分析:

    按边的颜色给边排个序,找出白边数量最多的生成树和白边数量最少的生成树。
    从白边最少到白边最多的过程中,树上白边的数量是连续变换的。(这个结论不太会证)
    所以如果这个区间中有斐波那契数那么答案就是存在
    注意要判断一下原图是否连通

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 100000 + 10;
    
    int n, m;
    
    struct Edge
    {
        int u, v, c;
        bool operator < (const Edge& e) const {
            return c > e.c;
        }
    }edges[maxn];
    
    int pa[maxn];
    int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); }
    
    int fib[100];
    
    int main() {
        fib[1] = 1; fib[2] = 2;
        for(int i = 3; i <= 25; i++) fib[i] = fib[i - 1] + fib[i - 2];
    
        int T; scanf("%d", &T);
        for(int kase = 1; kase <= T; kase++) {
            scanf("%d%d", &n, &m);
            for(int i = 0; i < m; i++) {
                scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].c);
            }
            sort(edges, edges + m);
    
            for(int i = 1; i <= n; i++) pa[i] = i;
            int cc = n, white1 = 0;
            for(int i = 0; i < m && cc > 1; i++) {
                Edge& e = edges[i];
                int pu = findset(e.u), pv = findset(e.v);
                if(pu == pv) continue;
                cc--;
                pa[pu] = pv;
                if(e.c == 1) white1++;
            }
    
            if(cc > 1) { printf("Case #%d: No
    ", kase); continue; }
    
            for(int i = 1; i <= n; i++) pa[i] = i;
            cc = n;
            int white2 = 0;
            for(int i = m - 1; i >= 0 && cc > 1; i--) {
                Edge& e = edges[i];
                int pu = findset(e.u), pv = findset(e.v);
                if(pu == pv) continue;
                cc--;
                pa[pu] = pv;
                if(e.c == 1) white2++;
            }
    
            //printf("%d %d
    ", white2, white1);
    
            bool ok = false;
            for(int i = 1; i <= 24; i++) if(white2 <= fib[i] && fib[i] <= white1) {
                ok = true; break;
            }
    
            printf("Case #%d: %s
    ", kase, ok ? "Yes" : "No");
        }
    
        return 0;
    }
    
  • 相关阅读:
    android 源码下载(Windows+Linux)
    Android Studio依赖包冲突 Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
    深入了解Java--1 绪论
    Android Studio 找不到R文件解决方法汇总
    Git学习历程
    word自动生成目录左对齐(缩进)问题
    Android Studio simpleUML(UML工具)使用详解
    android studio 常用快捷键
    当我们提起“女性权益”的时候,我们到底指的是什么?
    weakref模块和弱引用
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4909357.html
Copyright © 2020-2023  润新知