Fibonacci Tree

题意:
给一个 N N N个点 M M M条边的图,M条边分为白边和黑边,白边用 1 1 1表示黑边用 0 0 0表示,问是否有菲薄那切条白边的生成树存在。
求最小生成树和最大生成树,其中包含白边为 0 − > k 0->k 0>k的数量的生成树,特判无法组成生成树的图。
参考代码:

/*
/*
 * @Author: vain
 * @Date: 2020
 * @LastEditTime: 2020-09-15 15:47:43
 * @LastEditors: sueRimn
 * @Description: 学不会 dp 的 fw
 * @FilePath: \main\demo.cpp
 */
//#include <bits/stdc++.h>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
#include <bitset>
using namespace std;
typedef long long ll;
#define ll long long
typedef unsigned long long ull;
const int N = 1e3 + 20;
const ll maxn = 1e5 + 20;
const ll mod = 998244353;
ll head[maxn], stac[maxn], pre[maxn];
ll a[maxn], b[maxn], c[maxn], vis[maxn], sizx[maxn];
// typedef pair<ll, ll> p;
// priority_queue<p, vector<p>, greater<p>> m;
ll sum[maxn];
int max(int a, int b) {
    
     return a > b ? a : b; }
ll min(ll a, ll b) {
    
     return a < b ? a : b; }
ll gcd(ll a, ll b) {
    
     return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) {
    
     return a * b / gcd(a, b); }
void swap(ll &x, ll &y) {
    
     x ^= y, y ^= x, x ^= y; }
map<int, int> mp;
int ik[N], q[N], cnt;
int lowbit(int x) {
    
     return (x) & (-x); }
//vector<ll> f;
// ull h[maxn], p[maxn];
const ull base = 13331;
char s1[maxn];
ll ksm(ll a, ll b, ll mod)
{
    
    
    ll res = 1;
    while (b)
    {
    
    
        if (b & 1)
            res = (a * res) % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}
struct node
{
    
    
    int a, b, w;
} p[maxn];
bool cmp(node x, node y)
{
    
    
    return x.w < y.w;
}
bool cnp(node x, node y)
{
    
    
    return x.w > y.w;
}
int f(int x)
{
    
    
    if (x != pre[x])
        pre[x] = f(pre[x]);
    return pre[x];
}
void init(int n)
{
    
    
    for (int i = 0; i <= n; i++)
        pre[i] = i;
}
void join(int a, int b)
{
    
    
    a = f(a), b = f(b);
    if (a != b)
        pre[a] = b;
}
int krsual(int n, int m)
{
    
    
    int ans = 0, k = 0;
    for (int i = 0; i < m; i++)
    {
    
    
        if (f(p[i].a) == f(p[i].b))
            continue;
        join(p[i].a, p[i].b);
        ans += p[i].w;
        k++;
        if (k == n - 1)
            break;
    }
    return k == (n-1) ? ans : 0;
}
void inp()
{
    
    
    for (int a = 0, b = 1, c = 1; c < maxn; c = b + a)
    {
    
    
        mp[c] = 1, a = b, b = c;
    }
}
int main()
{
    
    
    // ios::sync_with_stdio(false);
    // cin.tie(0), cout.tie(0);
    // srand(time(NULL));
    inp();
    int t, n, m;
    inp();
    scanf("%d", &t);
    for (int j = 1; j <= t; j++)
    {
    
    
        scanf("%d %d", &n, &m);
        init(n);
        for (int i = 0; i < m; i++)
        {
    
    
            scanf("%d %d %d", &p[i].a, &p[i].b, &p[i].w);
        }
        sort(p, p + m, cmp);
        int k = krsual(n, m);
        init(n);
        sort(p, p + m, cnp);
        int k1 = krsual(n, m);
        bool fla = true;
        for (int i = k; i <= k1; i++)
        {
    
    
            if (mp[i])
            {
    
    
                printf("Case #%d: Yes\n", j);
                fla = false;
                break;
            }
        }
        if (fla)
        {
    
    
            printf("Case #%d: No\n", j);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/108601093