Last Theorem CodeForces - 1325F(dfs树找最大环+思维)

It’s the year 5555. You have a graph, and you want to find a long cycle and a huge independent set, just because you can. But for now, let’s just stick with finding either.

Given a connected graph with n vertices, you can choose to either:

find an independent set that has exactly ⌈n−−√⌉ vertices.
find a simple cycle of length at least ⌈n−−√⌉.
An independent set is a set of vertices such that no two of them are connected by an edge. A simple cycle is a cycle that doesn’t contain any vertex twice. I have a proof you can always solve one of these problems, but it’s too long to fit this margin.

Input
The first line contains two integers n and m (5≤n≤105, n−1≤m≤2⋅105) — the number of vertices and edges in the graph.

Each of the next m lines contains two space-separated integers u and v (1≤u,v≤n) that mean there’s an edge between vertices u and v. It’s guaranteed that the graph is connected and doesn’t contain any self-loops or multiple edges.

Output
If you choose to solve the first problem, then on the first line print “1”, followed by a line containing ⌈n−−√⌉ distinct integers not exceeding n, the vertices in the desired independent set.

If you, however, choose to solve the second problem, then on the first line print “2”, followed by a line containing one integer, c, representing the length of the found cycle, followed by a line containing c distinct integers integers not exceeding n, the vertices in the desired cycle, in the order they appear in the cycle.

Examples
inputCopy
6 6
1 3
3 4
4 2
2 6
5 6
5 1
outputCopy
1
1 6 4
inputCopy
6 8
1 3
3 4
4 2
2 6
5 6
5 1
1 4
2 5
outputCopy
2
4
1 5 2 4
inputCopy
5 4
1 2
1 3
2 4
2 5
outputCopy
1
3 4 5

思路:和codeforces 649div2 D题差不多,都是dfs树的思路,但是这个题目比较难一些。
这个题目是dfs树找最大环。如果最大环符合第二个条件的话,就输出这个树中的点。如果不符合的话,就需要讨论了。
图片来源
Last Theorem CodeForces - 1325F(dfs树找最大环+思维)_第1张图片
代码如下:

#include
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;

const int maxx=1e5+100;
const int maxm=2e5+100;
struct edge{
	int to,next;
}e[maxm<<1];
int head[maxm<<1];
int f[maxx],dis[maxx],vis[maxx];
vector<int> p[maxx];
int n,m,tot,ans=0,pos;

inline void init()
{
	memset(f,0,sizeof(f));
	memset(dis,0,sizeof(dis));
	memset(vis,0,sizeof(vis));
	memset(head,-1,sizeof(head));
	tot=0;
}
inline void add(int u,int v)
{
	e[tot].to=v,e[tot].next=head[u],head[u]=tot++;
}
inline void dfs(int u,int fa,int h,int cor,int num)
{
	vis[u]=1;
	f[u]=fa;
	dis[u]=h;
	p[h%(num-1)].push_back(u);
	for(int i=head[u];i!=-1;i=e[i].next)
	{
		int to=e[i].to;
		if(to==fa) continue;
		else if(vis[to])
		{
			if(ans<abs(dis[u]-dis[to])+1)
			{
				ans=abs(dis[u]-dis[to])+1;
				pos=u;
			}
		}
		else dfs(to,u,h+1,cor^1,num);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	init();
	int x,y;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	int num=sqrt(n);
	if(num*num<n) num+=1;
	dfs(1,0,0,0,num);
	if(m==n-1||ans<num)
	{
		cout<<1<<endl;
		for(int i=0;i<num;i++)
		{
			if(p[i].size()>=num)
			{
				for(int j=0;j<num;j++) cout<<p[i][j]<<" ";
				cout<<endl;
				return 0;
			}
		}
	}
	else
	{
		cout<<2<<endl<<ans<<endl;
		for(;ans;ans--) cout<<pos<<" ",pos=f[pos];
		cout<<endl;
	}
}

努力加油a啊,(o)/~

你可能感兴趣的:(Last Theorem CodeForces - 1325F(dfs树找最大环+思维))