两个BUG鸣翠柳,一行代码上西天。。。最小生成树练习2(Kruskal)

hdu4786 Fibonacci Tree(生成树)问能否用白边和黑边构成一棵生成树,并且白边数量是斐波那契数。

题解:分别优先加入白边和黑边,求出生成树能包含白边的最大值和最小值,其间有值为斐波那契数即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int M=1e5+1;
 6 const int N=1e5+1;
 7 struct edge{
 8     int u,v,w;
 9 }e[M];
10 int f[N];
11 int fi[20];
12 int n,m,ans;
13 int cmp(edge a,edge b){
14     return a.w<b.w;
15 }
16 void init(){
17     for(int i=1;i<=n;++i) f[i]=i;
18 }
19 int fin(int x){
20     if(x!=f[x])f[x]=fin(f[x]);
21     return f[x];
22 }
23 void Kruskal(){
24     int u,v,i,cnt=0,mi=0,ma=0,flag=0;
25     init();
26     for(i=0;i<m;++i){
27         u=e[i].u;
28         v=e[i].v;
29         if((u=fin(u))!=(v=fin(v))){
30             f[u]=v;
31             if(e[i].w) mi++;
32             if(++cnt==n-1){flag=1;break;}
33         }
34     }
35     if(!flag){printf("No\n");return;}
36     init();
37     for(i=m-1;i>=0;--i){
38         u=e[i].u;
39         v=e[i].v;
40         if((u=fin(u))!=(v=fin(v))){
41             f[u]=v;
42             if(e[i].w) ma++;
43             if(++cnt==n-1)break;
44         }
45     }
46     for(i=1;i<20;++i)
47         if(mi<=fi[i]&&fi[i]<=ma){
48             printf("Yes\n");return;
49         }
50     printf("No\n");
51 }
52 int main(){
53     int t,i,a,b,c,k=1;
54     fi[1]=1;fi[2]=2;
55     for(i=3;i<20;++i)
56         fi[i]=fi[i-1]+fi[i-2];
57     //printf(".%d.",fi[19]);
58     scanf("%d",&t);
59     while(t--){
60         scanf("%d%d",&n,&m);
61         for(i=0;i<m;++i){
62             scanf("%d%d%d",&a,&b,&c);
63             e[i]={a,b,c};
64         }
65         sort(e,e+m,cmp);
66         printf("Case #%d: ",k++);
67         Kruskal();
68     }
69     return 0;
70 }
View Code

相关文章:

  • 2022-12-23
  • 2021-11-12
  • 2021-05-26
  • 2021-10-03
  • 2021-07-11
  • 2021-10-04
  • 2021-05-23
猜你喜欢
  • 2022-01-02
  • 2021-08-18
  • 2022-01-24
  • 2021-07-12
  • 2021-12-28
  • 2022-01-08
  • 2021-12-13
相关资源
相似解决方案