题意:
给你n个点和m条边,让你找一个大于等于⌈√n⌉的环或找一个点数等于⌈√n⌉的独立集
链接:https://codeforces.com/contest/1325/problem/F
思路:根据dfs树的原理,相同深度的点之间必定没有边相连,我们将点的深度从
0到⌈√n⌉-1进行划分,根据鸽巢原理,必定存在一个深度满足这个深度的点的数量
大于等于⌈√n⌉。
代码:
#include <bits/stdc++.h>
#include<windows.h>
using namespace std;
typedef long long ll;
const int MAXN=2e5+5;
const int INF=0x3f3f3f3f3f3f3f;
const int mod=998244353;
int head[MAXN],tot,limit;
struct node
{
int to,nxt;
} e[MAXN<<2];
void add(int x,int y)
{
e[tot].to=y;
e[tot].nxt=head[x];
head[x]=tot++;
}
void add_edge(int x,int y)
{
add(x,y);
add(y,x);
}
int fa[MAXN],num[MAXN],dep[MAXN];
void dfs(int u)
{
num[dep[u]%(limit-1)]++;
for(int i=head[u]; ~i; i=e[i].nxt)
{
int v=e[i].to;
if(v==fa[u])
continue;
if(dep[v]==-1)
{
dep[v]=dep[u]+1;
fa[v]=u;
dfs(v);
}
else
{
if(dep[u]-dep[v]+1>=limit)
{
cout<<"2"<<endl;
cout<<dep[u]-dep[v]+1<<endl;
for(int i=u; i!=v; i=fa[i])
cout<<i<<" ";
cout<<v<<endl;
exit(0);
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
cin>>n>>m;
memset(head,-1,sizeof(head));
memset(dep,-1,sizeof(dep));
for(int i=1; i<=m; i++)
{
int u,v;
cin>>u>>v;
add_edge(u,v);
}
limit=(int)ceil(sqrt(n));
dep[1]=0;
dfs(1);
int temp=*max_element(num,num+limit-1);
int cnt=0;
cout<<"1"<<endl;
for(int i=1; i<=n; i++)
{
if(num[dep[i]%(limit-1)]==temp)
cout<<i<<" ",cnt++;
if(cnt==limit)
break;
}
return 0;
}
来源:https://www.cnblogs.com/ljxdtc666/p/12565369.html