2 1 1 4 1 2
1
并查集 k <=1000000000 找到大于这个数的fib打个表就能判断了
【源代码】
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; ll f[1010]; ll k[1010]; int father[1010]; int num[1010]; void init(){ f[0] = 0; f[1] = 1; for(int i=2;i<=50;i++) f[i] = f[i-1] + f[i-2]; // printf("%lld\n",f[50]); } int Find(int x){ if(x == father[x]) return x; return father[x] = Find(father[x]); } void Union(int x,int y){ int xr = Find(x); int yr = Find(y); if(xr != yr) father[xr] = yr; } int main(){ int t; init(); int n,m; while(scanf("%d%d",&n,&m)!=EOF){ memset(num,0,sizeof(num)); for(int i=1;i<=n;i++){ scanf("%lld",&k[i]); father[i] = i; } for(int i=0;i<m;i++){ int a,b; scanf("%d%d",&a,&b); Union(a,b); } for(int i=1;i<=n;i++){ int flag = 0; for(int j=0;j<=50;j++){ if(k[i] == f[j]) flag = 1,j = 51; } if(flag){ int pos = Find(i); //查找一下,也就是状态压缩一下 //直接num[father[i]]++;就错了 num[pos] ++ ; } } int maxx = 0; for(int i=1;i<=n;i++){ maxx = max(maxx,num[i]); } printf("%d\n",maxx); } return 0; }