题目大意:一共有n个点,m条边,一个点到另一个点的距离等于这两个点斐波那契数之和,现要求联通这n个点,并且在路径最短的情况下输出度数最大的点的度数。
思路:当时比赛的时候想到了最小生成树,但是这个路径长度不会处理,数学是真的差,就一个斐波那契数列的性质都没想到,补的时候还以为要数据离散化,然而只要排个序,然后最小生成树就行了。
#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define mod 998244353
#define INF 0x3f3f3f
#define fi first
#define se second
#define it iterator
#define ins insert
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define ll long long
#define ull unsigned long long
#define mem(a) memset(a,0,sizeof(a))
#define cio ios::sync_with_stdio(false)
#define gcd __gcd
ll lgcd ( ll a, ll b) { return b == 0 ? a: lgcd ( b, a % b) ; }
int lowbit ( int x) { return x& ( - x) ; }
#define T int t;scanf("%d",&t);while(t--)
#define CE cout << endl
#define C(n) cout << n << endl
#define CY cout << "YES" << endl
#define CN cout << "NO" << endl
#define Cy cout << "Yes" << endl
#define Cn cout << "No" << endl
struct node
{
int x, y, z;
} s[ 200010 ] ;
int d[ 100010 ] ;
int q[ 100010 ] ;
bool cmp ( node a, node b)
{
if ( a. y!= b. y) return a. y < b. y;
return a. x < b. x;
}
int ffind ( int x)
{
if ( q[ x] != x) {
return q[ x] = ffind ( q[ x] ) ;
} else {
return q[ x] ;
}
}
void com ( int x, int y)
{
int xx = ffind ( x) ;
int yy = ffind ( y) ;
q[ yy] = xx;
}
int main ( )
{
int n, m;
cin >> n >> m;
for ( int i = 0 ; i <= n; i++ ) q[ i] = i;
for ( int i = 0 ; i < m; i++ ) {
cin >> s[ i] . x >> s[ i] . y;
if ( s[ i] . x> s[ i] . y) swap ( s[ i] . x, s[ i] . y) ;
}
sort ( s, s+ m, cmp) ;
int k = 1 ;
for ( int i = 0 ; i < m; i++ ) {
if ( k== n) break ;
int v1 = s[ i] . x;
int v2 = s[ i] . y;
if ( ffind ( v1) != ffind ( v2) ) {
com ( v1, v2) ;
d[ v1] ++ ;
d[ v2] ++ ;
k++ ;
}
}
int maxn = d[ 1 ] ;
for ( int i = 2 ; i <= n; i++ ) maxn = max ( maxn, d[ i] ) ;
C ( maxn) ;
return 0 ;
}