对生成树一些相关概念还是不清楚 学好离散数学很重要的
分别求最小和最大生成树 其值分别代表最少和最多可以用多少条白边构造生成树
既然上下界都已确定 那这个区间内的边数都是可以被满足的
#include <bits/stdc++.h>
using namespace std;
struct node
{
int u;
int v;
int w;
};
node edge[100010];
int f[100010],fab[100010];
int n,m,cnt,flag;
int cmp1(node n1,node n2)
{
return n1.w<n2.w;
}
int cmp2(node n1,node n2)
{
return n1.w>n2.w;
}
void init()
{
int pre[100010];
int i;
pre[1]=1,pre[2]=1;
fab[1]=1;
i=3;
while(pre[i-1]+pre[i-2]<=100000)
{
pre[i]=pre[i-1]+pre[i-2];
fab[pre[i]]=1;
i++;
}
return;
}
int getf(int p)
{
if(f[p]==p)
{
return p;
}
else
{
f[p]=getf(f[p]);
return f[p];
}
}
int unite(int u,int v)
{
int fu,fv;
fu=getf(u);
fv=getf(v);
if(fu!=fv)
{
f[fv]=fu;
return 1;
}
else
{
return 0;
}
}
int judge()
{
int i,cnt;
for(i=1;i<=n;i++)
{
f[i]=i;
}
flag=0,cnt=0;
for(i=1;i<=m;i++)
{
if(unite(edge[i].u,edge[i].v))
{
cnt++;
}
if(cnt==n-1)
{
flag=1;
break;
}
}
return flag;
}
int calculate()
{
int i,cnt,sum;
cnt=0,sum=0;
for(i=1;i<=m;i++)
{
if(unite(edge[i].u,edge[i].v))
{
cnt++,sum+=edge[i].w;
}
if(cnt==n-1) break;
}
return sum;
}
int main()
{
int t,cas,i,l,r;
init();
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
}
if(!judge())
{
printf("Case #%d: No\n",cas);
continue;
}
sort(edge+1,edge+m+1,cmp1);
for(i=1;i<=n;i++)
{
f[i]=i;
}
l=calculate();
sort(edge+1,edge+m+1,cmp2);
for(i=1;i<=n;i++)
{
f[i]=i;
}
r=calculate();
flag=0;
for(i=l;i<=r;i++)
{
if(fab[i])
{
flag=1;
break;
}
}
if(flag==1)
{
printf("Case #%d: Yes\n",cas);
}
else
{
printf("Case #%d: No\n",cas);
}
}
return 0;
}