题意:
给一个 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);
}
}
}