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 }