0
点赞
收藏
分享

微信扫一扫

HDOJ 4786 - Fibonacci Tree 理解生成树

灯火南山 2022-08-12 阅读 26


               题意:

                       给了一个无向图..每个边要么是白的.要么是黑的..问能否构造一个生成树..让白边在生成树的个数为fibonacci数...

               题解:

                       求出需要白边最少的和最多的生成树...如果在这两个数之间有fibonacci数则说明存在....原理是一个生成树构造成另一个生成树..必定可以不断的去边又加边来完成..所以如果所需白边最少和最多之间有fibonacci数则一定可以通过变换找出来....

                        而要找白边最多/最少的生成树..只需将所有边按颜色分成两堆..如果要白边最多.则每次尽可能的从白色的边里取边..取到没有白边可取了..再取黑边..如果要白边最少..则反之...


Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#define MAXN 100005
using namespace std;
struct node
{
int u,v,t,next;
}edge[MAXN];
bool cmp(node a,node b)
{
return a.t>b.t;
}
int father[MAXN];
bool fb[MAXN];
int getfather(int u)
{
if (father[u]==u) return u;
return father[u]=getfather(father[u]);
}
int getdata(int n,int m,int c)
{
int ans=0,u,v,t,p;
for (u=1;u<=n;u++) father[u]=u;
if (c==1) p=1;
else p=m;
for (;p>0 && p<=m;p+=c)
{
u=edge[p].u,v=edge[p].v,t=edge[p].t;
if (getfather(u)==getfather(v)) continue;
father[father[u]]=father[v];
ans+=t;
}
for (u=2;u<=n;u++)
if (getfather(u)!=getfather(1)) return 10;
return ans;
}
int main()
{
int C,cases,p,q,n,m,l,r;
q=p=1;
memset(fb,false,sizeof(fb));
while (p<=100000)
{
fb[p]=true;
m=p+q,q=p,p=m;
}
scanf("%d",&C);
for (cases=1;cases<=C;cases++)
{
scanf("%d%d",&n,&m);
for (p=1;p<=m;p++)
scanf("%d%d%d",&edge[p].u,&edge[p].v,&edge[p].t);
sort(edge+1,edge+1+m,cmp);
l=getdata(n,m,-1);
r=getdata(n,m,1);
for (p=l;p<=r;p++)
if (fb[p]) break;
printf("Case #%d: ",cases);
if (p<=r) puts("Yes");
else puts("No");
}
return 0;
}



举报

相关推荐

0 条评论