Fibonacci Tree
Time Limit : 4000/2000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 6 Accepted Submission(s) : 3
Problem Description
Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him to do some research on Spanning Tree. So Coach Pang decides to solve the following problem:
Consider a bidirectional graph G with N vertices and M edges. All edges are painted into either white or black. Can we find a Spanning Tree with some positive Fibonacci number of white edges?
(Fibonacci number is defined as 1, 2, 3, 5, 8, ... )
Consider a bidirectional graph G with N vertices and M edges. All edges are painted into either white or black. Can we find a Spanning Tree with some positive Fibonacci number of white edges?
(Fibonacci number is defined as 1, 2, 3, 5, 8, ... )
Input
The first line of the input contains an integer T, the number of test cases. For each test case, the first line contains two integers N(1 <= N <= 10[sup]5[/sup]) and M(0 <= M <= 10[sup]5[/sup]). Then M lines follow, each contains
three integers u, v (1 <= u,v <= N, u<> v) and c (0 <= c <= 1), indicating an edge between u and v with a color c (1 for white and 0 for black).
Output
For each test case, output a line “Case #x: s”. x is the case number and s is either “Yes” or “No” (without quotes) representing the answer to the problem.
Sample Input
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
Sample Output
Case #1: Yes Case #2: No#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; int a[100010]; int fb[26]={0,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025};//数很少,直接打表 int sum,ans; struct zz { int f1,f2,c; }q[100010]; int cmp(zz x,zz y) { return x.c<y.c; } /*int find(int x) //这种超时 { while(x!=a[x]) x=a[x]; return x; }*/ int find (int x) { int r=x; while(r!=a[r]) r=a[r]; int i=x,j; while(i!=r) { j=a[i]; a[i]=r; i=j; } return r; } void marge(int x,int y,int z) { int fx,fy; fx=find(x); fy=find(y); if(fx!=fy) { a[fx]=fy; ans++; //记录节点数,方便后面判断是否能形成树。 if(z==1) sum++;//记录白边的个数 } } int main() { int i,j,m,n,zd,zs,flag; int t,s=0; scanf("%d",&t); while(t--) { sum=0;ans=0; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) a[i]=i; for(i=0;i<m;i++) { scanf("%d%d%d",&q[i].f1,&q[i].f2,&q[i].c); } sort(q,q+m,cmp);//最小生成树,求出白边最少有几条 for(i=0;i<m;i++) { marge(q[i].f1,q[i].f2,q[i].c); } if(ans!=n-1)//如果不能形成树,直接输出No。 { printf("Case #%d: No\n",++s); continue; } zs=sum;//最少白边数量。 sum=0;//第二步,求最多有几条白边 for(i=1;i<=n;i++) a[i]=i; for(i=m-1;i>=0;i--) { marge(q[i].f1,q[i].f2,q[i].c); } zd=sum;//最多白边数量 flag=0; for(i=1;i<25;i++) { if(fb[i]>=zs&&fb[i]<=zd) flag=1; } if(flag) printf("Case #%d: Yes\n",++s); else printf("Case #%d: No\n",++s); } return 0; }