zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    从习总书记讲话学习表达
    Struts——(四)异常处理机制
    Struts框架——(三)动态ActionForm
    Struts框架——(二)Struts原理with登录实例
    Serializable接口和transient关键字
    转发(forward)和重定向(sendRedirect)
    Struts框架——(一)用Servlet + JSP演示Struts基本原理
    Cookie & Session
    Servlet
    SSH框架
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4909357.html
Copyright © 2011-2022 走看看