2 4 4 1 2 1 2 3 1 3 4 1 1 4 0 5 6 1 2 1 1 3 1 1 4 1 1 5 1 3 5 1 4 2 1
Case #1: Yes Case #2: No
一开始超时的十几遍,就是不知道为啥错,后来写3560的时候也是超时,无意中发现头文件如果是#include<stdio.h>就AC,当时想哭的心都有的。以后再也不用#incldue<cstdio>了。
///* //题目大意:给定一个图,确定是一个连通图。每条边有一定的颜色,黑或白。求是否有这样一棵生成树保证所有的树边的总数为一个Fibonacci数。 //解题思路: //按边的颜色排序两次,一次黑边优先,利用并查集构造一个生成树,此时是所有方法中白边最少的情况,x。 //而后白边优先,得出的是白边最多的情况,y。找找x,y二者之间是否包括一个Fibonacci数即可。 //*/ #include <stdio.h> #include <string.h> #include <algorithm> #define maxn 100100 using namespace std; struct node { int u,v,c; }; int cmp1(node a,node b){ return a.c<b.c; } int cmp2(node a,node b){ return a.c>b.c; } int p[maxn]; node s[maxn]; int n,m,ans; int find(int x){ if(x==p[x]) return p[x]; return p[x]=find(p[x]); } int a[35]; void fib(){ a[1]=1; a[2]=2; for(int i=3;i<30;++i) a[i]=a[i-1]+a[i-2]; } int check (int l,int r){ if(l==-1 || r==-1) return 0; for(int i=1;i<30;++i){ if(l<=a[i] && a[i]<=r) return 1; } return 0; } int main(){ int t,i,q=0; scanf("%d",&t); fib(); while(t--){ scanf("%d%d",&n,&m); for(i=0;i<m;++i) scanf("%d%d%d",&s[i].u,&s[i].v,&s[i].c); for(int i=0;i<=n;++i) p[i]=i; sort(s,s+m,cmp1); int sum=0; ans=0; int num1,num2; for(i=0;i<m;++i){ int fa=find(s[i].u); int fb=find(s[i].v); if(fa!=fb){ p[fa]=fb; sum+=s[i].c; } } for(i=1;i<=n;++i){ if(p[i]==i) ans++; if(ans>1) num1=-1; else num1=sum; } // printf("sum=%d\n",sum); sum=0; ans=0; for(int i=0;i<=n;++i) p[i]=i; sort(s,s+m,cmp2); for(i=0;i<m;++i){ int fa=find(s[i].u); int fb=find(s[i].v); if(fa!=fb){ p[fa]=fb; sum+=s[i].c; } } for(i=1;i<=n;++i){ if(p[i]==i) ans++; if(ans>1) num2=-1; else num2=sum; } // printf("sum1=%d\n",sum); // printf("%d %d \n",num1,num2); if(check(num1,num2)){ printf("Case #%d: ",++q); printf("Yes\n"); } else{ printf("Case #%d: ",++q); printf("No\n"); } } return 0; }