Codeforces 1325 F Ehabs Last Theorem —— dfs树

82 篇文章 1 订阅

This way

题意:

给你一张图,你有两种选择:
1.找到里面一个大小为 ⌈ n ⌉ \lceil\sqrt{n}\rceil n 的独立集
2.找到里面一个长度大于等于 ⌈ n ⌉ \lceil\sqrt{n}\rceil n 的简单环

题解:

很久没写程序了,都有点生疏。
那么这道题一开始如果当成一张图去想的话我觉得很难想,但是众所周知连通图图其实可以看成在一棵生成树上加边。那么选择2就很简单了:
对于找到的生成树上深度相差这么多的两个连通的点就是所要求的简单环
如果没有呢,那么我们将每个点的深度取模 ⌈ n ⌉ − 1 \lceil\sqrt{n}\rceil-1 n 1,那么其中至少有一个深度的点的数量>= ⌈ n ⌉ \lceil\sqrt{n}\rceil n 。这就是鸽巢原理。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int num[N],cnt;
struct node{
    int to,next;
}e[N*2];
int tot,head[N],dep[N],mod;
void add(int x,int y){
    e[tot].to=y;
    e[tot].next=head[x];
    head[x]=tot++;
}
stack<int>st;
void dfs(int x,int fa){
    dep[x]=dep[fa]+1;
    num[dep[x]%mod]++;
    st.push(x);
    for(int i=head[x];~i;i=e[i].next){
        int ne=e[i].to;
        if(ne==fa)continue;
        if(dep[ne]||ne==1){
            if(dep[x]-dep[ne]+1>=cnt){
                printf("2\n%d\n",dep[x]-dep[ne]+1);
                while(1){
                    printf("%d\n",st.top());
                    if(st.top()==ne)break;
                    st.pop();
                }
                exit(0);
            }
            continue;
        }
        dfs(ne,x);
    }
    st.pop();
}
int main()
{
    memset(head,-1,sizeof(head));
    int n,m,x,y;
    scanf("%d%d",&n,&m);
    mod=sqrt(n);
    if(mod*mod!=n)mod++;
    cnt=mod;
    mod--;
    for(int i=1;i<=m;i++)
        scanf("%d%d",&x,&y),add(x,y),add(y,x);
    dep[0]=-1;
    dfs(1,0);
    int ans;
    for(int i=0;i<mod;i++){
        if(num[i]>=cnt){
            printf("1\n");
            for(int j=1;j<=n;j++){
                if(dep[j]%mod==i)
                    printf("%d\n",j),cnt--;
                if(!cnt)
                    exit(0);
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值