Codeforces Round #628 (Div. 2) F——Ehab's Last Theorem dfs

Posted qingyuyyyyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #628 (Div. 2) F——Ehab's Last Theorem dfs相关的知识,希望对你有一定的参考价值。

#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
using namespace std;

typedef long long ll;
const int p=1e8+7;


vector<int>v[1001000],ans;
int d[100010],vis[100100],nd;
void dfs(int x,int fa)
{
    ans.push_back(x);
    d[x]=ans.size();//x在ans中的位置 
    for(auto i:v[x])
    {
        if(i==fa) continue;
        if(!d[i]) dfs(i,x);//如果没有遍历过,往下遍历 
        else if(d[x]-d[i]+1>=nd)//如果已经遍历过,说明是个环,判断环的大小 
        {
            printf("2
%d
",d[x]-d[i]+1);//环的大小 通过在ans中的编号搞出来 
            for(int j=d[i]-1; j<d[x]; j++) printf("%d ",ans[j]);//输出环,因为在vector种下标的缘故,整体要往左移动一个单位 
            printf("
");
            exit(0);
        }
    }
    //如果x没有遍历过  记得把和x相邻的 都标记,为了第一种答案
    if(!vis[x])
    {
        for(auto i:v[x]) vis[i]=1;
    }
    //相当于反向回溯,因为他要的独立集,是不相邻的,处理最后一个元素时,把和她相邻的都标记,然后把最后一个删掉,删掉的记作x,然后再往回
    //如果此时最后的 和 x 相邻,那么已经被标记过,也就不能再执行上面的语句了,就直接被删掉
    //这样不会出现重复被标记的问题
    ans.pop_back();
}
int main()
{
    int n,m,x,y;
    scanf("%d%d",&n,&m);
    nd=sqrt(n);
    if(nd*nd<n) nd++;
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d",&x,&y);
        v[x].push_back(y),v[y].push_back(x);
    }
    dfs(1,0);
    printf("1
");
    for(int i=1; i<=n&&nd; i++) if(!vis[i]) printf("%d ",i),nd--;
}

 

以上是关于Codeforces Round #628 (Div. 2) F——Ehab's Last Theorem dfs的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #628 (Div. 2) B.CopyCopyCopyCopyCopy(Set)

Codeforces Round #628 (Div. 2) C

Codeforces Round #628 (Div. 2) F——Ehab's Last Theorem dfs

Codeforces Round #628 (Div. 2) D. Ehab the Xorcist(异或,思维题)

Codeforces Round #628 (Div. 2) C.Ehab and Path-etic MEXs(图论,思维题)

二进制构造Codeforces Round #628 (Div. 2) D. Ehab the Xorcist