hdu4786 Fibonacci Tree (最小生成树)

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

题意:给定图的n个点和m条双向边,告诉你每条边的权值。权值为1表示该边是白边,权值为0表示该边为黑边。

问能否找到一颗生成树,使生成树白边的个数刚好为fibonacci数。如果能构成输出yes,否则输出no。

思路:这里有一个点要知道。因为是0,1 tree。   最小生成树<=生成树的值<=最大生成树。  注意,这个区间的任意一个值都能取到。

   但是如果不是0,1 tree,权值就不是任意可取的了,这个要具体计算的(排列组合,这里先不考虑)。

   剩下的看代码很容易懂。

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
const int maxn=1e5+5;
const int INF=0x3f3f3f3f;

struct Node
{
    int u,v,w;
} node[maxn*2];

int n,m;
int p[maxn];
int F[30];

int cmp1(Node x,Node y)
{
    return x.w<y.w;
}

int cmp2(Node x,Node y)
{
    return x.w>y.w;
}

int Find(int x)
{
    if(x!=p[x]) p[x]=Find(p[x]);
    return p[x];
}

void Union(int x,int y)
{
    x=Find(x);
    y=Find(y);
    p[y]=x;
}

int kruskal()
{
    int q=0,ans=0;
    for(int i=1; i<=m; i++)
    {
        if(Find(node[i].u) != Find(node[i].v))
        {
            ans+=node[i].w;
            Union(node[i].u,node[i].v);
            q++;
        }
        if(q==n-1) break;
    }
    return ans;
}

int main()
{
    F[1]=1,F[2]=2;
    int t;
    for(t=3; F[t]<maxn; t++)
        F[t]=F[t-1]+F[t-2];
    int T;
    scanf("%d",&T);
    for(int tt=1; tt<=T; tt++)
    {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=m; i++)
            scanf("%d%d%d",& node[i].u,& node[i].v,&node[i].w);
        int minn,maxx;

        for(int i=1; i<=n; i++) p[i]=i;
        sort(node+1,node+1+m,cmp1);
        minn=kruskal();

        for(int i=1; i<=n; i++) p[i]=i;
        sort(node+1,node+1+m,cmp2);
        maxx=kruskal();

        int flag=0;
        for(int i=1; i<t; i++)
            if(F[i]>=minn && F[i]<=maxx)
            {
                flag=1;
                break;
            }
        int fa=Find(1);
        for(int i=1; i<=n; i++)
            if(Find(i)!=fa)
            {
                flag=0;
                break;
            }
        if(flag==1) printf("Case #%d: Yes\n",tt);
        else printf("Case #%d: No\n",tt);
    }
    return 0;
}
时间: 2024-08-07 00:18:02

hdu4786 Fibonacci Tree (最小生成树)的相关文章

HDU 4786 Fibonacci Tree 最小生成树变形

思路: 这题比赛的时候想了好久,最后队友机智的想到了. 不过那时不是我敲的,现在敲的1A. 想好就容易了. 直接把1或者0当做边的权值,然后按边从小到大排序,然后算最小生成用到了几条白边,然后再按边从大到小排序,然后再算白边用了几条.然后最小和最大需要用到的白边都算出来了.如果在这最小最大区间中存在那个啥数列的话就是Yes,否则就是No. 为什么在这区间里面就是对的呢?刚开始我也想了好久,然后发现,因为白边权值是1,然后黑边是0,然后假设用到白边最小的是6,最大的是10,那么,我们可以用黑边去替

HDU--4786 Fibonacci Tree 生成树+贪心?

N个顶点,M条边,每条边可能为黑色或是白色( 0 or 1 ),问有没有可能用为斐波那契数的数目的白色边构成一棵生成树.所以需要删掉图中的环,根据每次删掉的边有一个白色边的上限和下限,判断一下中间有没有斐波那契数就可以了.实现方法是根据颜色排序,先放黑色边得到的是最小数目的白色边构成的生成树,先放白色边得到是最大数目的白色边构成的生成树. #include<cstring> #include<string> #include<fstream> #include<i

hdu 4786 Fibonacci Tree ( 最小生成树 )

Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2487    Accepted Submission(s): 796 Problem Description Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him t

HDU4786 Fibonacci Tree【最小生成树】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4786 题目大意: 给你图的N个点和M条双向边.告诉你每条边的权值.权值为1表示该边是白边,权值为0表示该 边为黑边.问:能否找到一棵生成树,使生成树白边的个数恰好为fibonacci数.如果能构成这样 的fibonacci树,输出Yes,否则输出No. 思路: 先将fibonacci数列打表.然后根据题意构图.然后根据边的权值大小排序,用Kruskal先求一遍 最小生成树,再求一遍最大生成树.如果

【最小生成树】【kruscal】hdu4786 Fibonacci Tree

假设这张图能够形成具有k条白边的生成树, 则易证k一定形成一个连续的区间[a,b],中间一定不会断开.要是断开--tm怎么可能. 所以求出a,b就好啦,人家都给你把白边赋成1了,直接跑一下最小生成树,再跑一下最大生成树即可咯. #include<cstdio> #include<algorithm> using namespace std; #define N 100010 struct Edge{ int u,v,w; }edges[N]; bool cmp(const Edge

[HDOJ4786]Fibonacci Tree 最小生成树

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4786 先跑一遍最小生成树,注意判断是否已全部联通(用一个记号来统计最后生成树中有多少条边).再记下最小生成树的权值和A. 再反向排序,求一遍最大生成树.记下权值和B.问题转换成求[A,B]内是否有斐波那契数存在. 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <

hdu 4786 Fibonacci Tree (最小生成树扩展)

///白边优先和黑边优先做两次最小生成树 ///若有斐波那契树在这中间为yes # include <stdio.h> # include <algorithm> # include <iostream> # include <string.h> # include <math.h> using namespace std; struct node { int x; int y; int v; }; struct node a[100010];

Fibonacci Tree(最小生成树,最大生成树)

Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3006    Accepted Submission(s): 966 Problem Description Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him to

hdu 4786 Fibonacci Tree(最小生成树)

Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2952    Accepted Submission(s): 947 Problem Description Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him t