题意:问生成树里能不能有符合菲波那切数的白边数量
思路:白边 黑边各优先排序求最小生成树,并统计白边在两种情况下数目,最后判断这个区间就可以。注意最初不连通就不行。
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 }
时间: 2024-12-19 17:49:57