如果圖中不存在長度大于等于??的環(huán),也就是說在 dfs 樹上的任意兩個(gè)點(diǎn) x , y 如果距離大于等于??的話,?一定是沒有非樹邊相連的,這樣我們就可以在取獨(dú)立集時(shí),每次都取相距恰好為??的點(diǎn),換句話說,這些點(diǎn)的深度 deep 在對??取模后都是相同的,根據(jù)鴿巢原理,一共有??組,一共有 n 個(gè)點(diǎn),n 個(gè)點(diǎn)分成??組,即下面的這個(gè)公式顯然成立,?,換句話說,肯定有一組中的個(gè)數(shù)是大于等于??的,也就滿足了第一種情況,證畢
證明結(jié)束后,我們就可以在dfs樹上找到最大環(huán),然后分類討論了
代碼: ?
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;typedef long long LL;typedef unsigned long long ull;const LL inf=0x3f3f3f3f;const int N=2e5+100;int n,m,d,deep[N],pre[N],cnt[N];vector<int>node[N];void dfs(int u,int fa,int dep)
{deep[u]=dep;pre[u]=fa;for(auto v:node[u]){if(v==fa)continue;if(deep[v]!=0){if(deep[u]-deep[v]+1>=0&&deep[u]-deep[v]+1>=d){puts("2");printf("%d\n",deep[u]-deep[v]+1);int num=deep[u]-deep[v]+1,pos=u;while(num--){printf("%d ",pos);pos=pre[pos];}exit(0);}}elsedfs(v,u,dep+1);}
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);scanf("%d%d",&n,&m);d=sqrt(n);if(d*d<n)d++;while(m--){int u,v;scanf("%d%d",&u,&v);node[u].push_back(v);node[v].push_back(u);}dfs(1,-1,1);for(int i=1;i<=n;i++)cnt[deep[i]%(d-1)]++;int mark=max_element(cnt,cnt+d-1)-cnt;vector<int>ans;for(int i=1;i<=n;i++)if(deep[i]%(d-1)==mark)ans.push_back(i);puts("1");for(int i=0;i<d;i++)printf("%d ",ans[i]);return 0;
}