Fibonacci Tree
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6672 Accepted Submission(s): 2049
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, ... )
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 <= 105) and M(0 <= M <= 105).
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
求出最小生成树与最大生成树,统计白边的数量min,max,因为树的边权值为0或1,所以[min,max]区间里每一个数都存在一棵最小生成树与之对应,判断[min,max]中是否有斐波那契数就行了。注意给的图有可能不连通
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;
typedef long long ll;
int a[30];
int pre[MAXN];
struct node
{
int u,v,c;
}e[MAXN];
bool cmp1(struct node a,struct node b)
{
return a.c > b.c;
}
bool cmp2(struct node a,struct node b)
{
return a.c < b.c;
}
int Find(int x)
{
if(x == pre[x]) return x;
else return pre[x] = Find(pre[x]);
}
bool join(int x,int y)
{
int fx = Find(x);
int fy = Find(y);
if(fx != fy) {
pre[fy] = fx;
return 1;
}
return 0;
}
int n;
void init()
{
for(int i = 1; i <= n; i++) pre[i] = i;
}
int main(void)
{
a[0] = 1,a[1] = 2;
int num;
for(int i = 2; i < 25; i++) {
a[i] = a[i - 1] + a[i - 2];
num = i;
if(a[i] > 100000) break;
}
int T;
int m;
scanf("%d",&T);
int kase = 0;
while(T--) {
kase++;
scanf("%d %d",&n,&m);
for(int i = 1; i <= m; i++) {
scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].c);
}
sort(e + 1,e + 1 + m,cmp1);
init();
int c1 = 0,c2 = 0;
int cnt = 0;
for(int j = 1; j <= m; j++) {
int u = e[j].u,v = e[j].v;
if(join(u,v)) {
if(e[j].c) c1++;
cnt++;
}
}
if(cnt != n - 1) {
printf("Case #%d: No\n",kase);
continue;
}
sort(e + 1,e + 1 + m,cmp2);
init();
for(int j = 1; j <= m; j++) {
int u = e[j].u,v = e[j].v;
if(join(u,v)) {
if(e[j].c) c2++;
}
}
int flag = 0;
for(int i = 0; i < num; i++) {
if(c2 <= a[i] && a[i] <= c1) {
flag = 1;
break;
}
}
//printf("%d %d\n",c1,c2);
if(flag) printf("Case #%d: Yes\n",kase);
else printf("Case #%d: No\n",kase);
}
return 0;
}
/*
22
1 0
Case #1: No
5 10
1 2 1
1 3 1
2 4 1
3 5 1
2 4 0
3 5 1
2 4 0
2 4 0
1 3 1
2 5 1
Case #2: No
*/