http://acm.hdu.edu.cn/showproblem.php?pid=4786php
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, ... )node
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).c++
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.ide
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 1spa
Case #1: Yes
Case #2: Norest
给你一个由白边和黑边组成的图,问你能不能找到一个生成树,使得白边的个数是Fibonacci数code
考虑白边最多状况的生成树时候白边数量为Max,最少的时候为Minthree
那么[Min,Max]这个区间内的白边数量均可以取到ip
因此求出Min和Max便可ci
坑点:图不联通
#include<bits/stdc++.h> using namespace std; const int maxn = 2e5+7; struct node{ int x,y,z; }p[maxn]; bool cmp1(node A,node B){ return A.z<B.z; } bool cmp2(node A,node B){ return A.z>B.z; } int fa[maxn]; int fi(int x){ return x==fa[x]?x:fa[x]=fi(fa[x]); } void uni(int x,int y){ x=fi(x),y=fi(y); if(x==y)return; else fa[x]=fa[y]; } void solve(int Cas){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z); sort(p+1,p+1+m,cmp1); int x1=0,x2=0; int D = 0; for(int i=1;i<=m;i++){ if(fi(p[i].x)!=fi(p[i].y)){ x1+=p[i].z; uni(p[i].x,p[i].y); D = D + 1; } } if(D!=n-1){ printf("Case #%d: No\n",Cas); return; } for(int i=1;i<=n;i++) fa[i]=i; sort(p+1,p+1+m,cmp2); for(int i=1;i<=m;i++){ if(fi(p[i].x)!=fi(p[i].y)){ x2+=p[i].z; uni(p[i].x,p[i].y); } } long long a=1,b=1; int flag = 0; while(a<=x2||b<=x2){ if(a>=x1&&a<=x2) flag=1; if(b>=x1&&b<=x2) flag=1; a=a+b; if(a>b)swap(a,b); } if(a>=x1&&a<=x2) flag=1; if(b>=x1&&b<=x2) flag=1; if(flag)printf("Case #%d: Yes\n",Cas); else printf("Case #%d: No\n",Cas); } int main(){ int t; scanf("%d",&t); for(int cas=1;cas<=t;cas++)solve(cas); }