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树找最大环。如果最大环符合第二个条件的话,就输出这个树中的点。如果不符合的话,就需要讨论了。
图片来源
在这里插入图片描述
代码如下:

#include<bits/stdc++.h>
#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)/~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值