HDU 4786 Fibonacci Tree (2013成都1006题) 最小生成树+斐波那契

题意:问生成树里能不能有符合菲波那切数的白边数量

思路:白边 黑边各优先排序求最小生成树,并统计白边在两种情况下数目,最后判断这个区间就可以。注意最初不连通就不行。

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include<cmath>
 5 #define LL long long
 6 using namespace std;
 7 int t,n,m;
 8 int tot;
 9 int F[100010];
10 struct node {
11     int u,v,c;
12 } edge[100010];
13 int f[100010];
14 void init() {
15     f[0]=1;
16     f[1]=1;
17     tot=1;
18     while(f[tot]<=100010) {
19         f[tot+1]=f[tot]+f[tot-1];
20         tot++;
21     }
22 }
23 
24 int findd(int x) {
25     if(F[x]==-1) return x;
26     else return F[x]=findd(F[x]);
27 }
28 bool cmp1(node a,node b) {
29     return a.c<b.c;
30 }
31 bool cmp2(node a,node b) {
32     return a.c>b.c;
33 }
34 int main() {
35     scanf("%d",&t);
36     int cas=0;
37     init();
38     while(t--) {
39         scanf("%d%d",&n,&m);
40         cas++;
41         for(int i=0; i<m; i++) {
42             scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c);
43         }
44         sort(edge,edge+m,cmp1);
45         memset(F,-1,sizeof(F));
46         int cnt=0;
47         for(int i=0; i<m; i++) {
48             int x=findd(edge[i].u);
49             int y=findd(edge[i].v);
50             if(x!=y) {
51                 F[x]=y;
52                 if(edge[i].c==1)
53                     cnt++;
54             }
55         }
56         int low=cnt;
57         cnt=0;
58         memset(F,-1,sizeof(F));
59         sort(edge,edge+m,cmp2);
60         for(int i=0; i<m; i++) {
61             int x=findd(edge[i].u);
62             int y=findd(edge[i].v);
63             if(x!=y) {
64                 F[x]=y;
65                 if(edge[i].c==1)
66                     cnt++;
67             }
68         }
69         int high=cnt;
70         int flag=0;
71         for(int i=1; i<=n; i++) {
72             if(findd(1)!=findd(i)) {
73                 flag=1;
74                 break;
75             }
76         }
77         if(flag) {
78             printf("Case #%d: No\n",cas);
79             continue;
80         }
81         flag = false;
82         for(int i = 0; i <= tot; i++)
83             if(f[i] >= low && f[i] <= high)
84                 flag = true;
85         if(flag)
86             printf("Case #%d: Yes\n",cas);
87         else printf("Case #%d: No\n",cas);
88 
89     }
90     return 0;
91 }
View Code

 

posted @ 2016-03-20 16:40  yyblues  阅读(253)  评论(0编辑  收藏  举报