HDU 4786 生成树

来源:互联网 发布:2017最网络语言 编辑:程序博客网 时间:2024/06/06 07:18

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

题意:给出权值为1或者0的边集,求是否可以构造出一颗权值为斐波那契数的生成树

题解:求出最小和最大生成树的权值l和r,对于任意l<x<r,必然可以添加一条边获得x+1或者去掉一条边获得x-1,故在[l, r]范围内生成树都可以构造,判断[l, r]范围内是否有斐波那契数输出即可

代码:

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;int num[40];void make(){    num[1] = 1; num[2] = 2;    for(int i = 3; i <= 30; i++) num[i] = num[i - 1] + num[i - 2];}struct node{    int a, b, c;}e[100010];int f[100010];int cmp1(node a, node b){    return a.c < b.c;}int cmp2(node a, node b){    return a.c > b.c;}int find(int x){    if(f[x] == x) return x;    f[x] = find(f[x]);    return f[x];}int main(){    //freopen("test.in", "r", stdin);    int n, m;    int tt;    scanf("%d", &tt);    make();    for(int ii = 0; ii < tt; ii++)    {        printf("Case #%d: ", ii + 1);        scanf("%d%d", &n, &m);        for(int i = 0; i < m; i++) scanf("%d%d%d", &e[i].a, &e[i].b, &e[i].c);        sort(e, e + m, cmp1);        for(int i = 0; i <= n; i++) f[i] = i;        int j = 0;        int l = 0;        int cc = 0;        for(int i = 0; i < m; i++)        {            while(j < m)            {                if(find(e[j].a) != find(e[j].b))                {                    l += e[j].c;                    f[find(e[j].a)] = find(e[j].b);                    cc++;                    break;                }                j++;            }        }        if(cc != n - 1) { puts("No"); continue; }        sort(e, e + m, cmp2);        for(int i = 0; i <= n; i++) f[i] = i;        int r = 0;        j = 0;        for(int i = 0; i < m; i++)        {            while(j < m)            {                if(find(e[j].a) != find(e[j].b))                {                    r += e[j].c;                    f[find(e[j].a)] = find(e[j].b);                    cc++;                    break;                }                j++;            }        }        bool flg = false;        for(int i = 1; num[i] <= m; i++) if(l <= num[i] && num[i] <= r) {flg = true; break;}        if(flg) puts("Yes");        else puts("No");    }    return 0;}


0 0