CF 1325F - Ehab's Last Theorem

Posted scnucjh

tags:

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

首先:

无向图的dfs树无横边

这很显然,因为若有u->v 为横边,那么v早就从这条边过来找u了...矛盾

(k = ceil( sqrt{n} ))

接下来跑dfs树,如果有回边使得环大于等于k,就输出环。

否则,说明一个问题:所有点的回边的数量都小于k(不然一定能找到环了,鸽巢原理~)

于是,可以不停自底向上地选取点为独立集点,同时把它的领边都标记为不能取为独立集。

结果一定至少有k个独立集点。

为什么? 因为前面说了,所有点的回边的数量都小于k,这样取点,每去一次点,最多标记k-1个点为非独立集。

代码中,flag[i] = 1 表示(i)已经标为不是独立集点。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 1e5+5;
bool flag[N];
int fa[N], dep[N];

int n,m,k;
vector<int> G[N];

void dfs(int x,int f,int d) {
    dep[x] = d;
    fa[x] = f;
    for(auto y:G[x]) {
        if(dep[y]==0)
            dfs(y,x,d+1);
        if(dep[x]-dep[y]+1>=k) {
            cout<<2<<endl;
            cout<<dep[x]-dep[y]+1<<endl;
            cout<<y<<" ";
            int z = x;
            while(z!=y) {
                cout<<z<<" ";
                z = fa[z];
            }
            exit(0);
        }
    }
    if(!flag[x])
        for(auto y:G[x]) {
            flag[y] = 1;
        } 
}

int main() {
    ios::sync_with_stdio(0);
    cin>>n>>m;
    while(k*k<n) k++;

    for(int i=0,a,b;i<m;i++) {
        cin>>a>>b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    dfs(1,0,1);
    cout<<1<<endl;
    for(int i=1; k; i++) {
        if(flag[i]) continue;
        cout<<i<<" ";
        k--;
    }
    return 0;
}

以上是关于CF 1325F - Ehab's Last Theorem的主要内容,如果未能解决你的问题,请参考以下文章

CF1364D Ehab‘s Last Corollary(思维,环,二分图,构造)

CF1364D Ehab‘s Last Corollary(思维,环,二分图,构造)

CF D. Ehab and the Expected XOR Problem 贪心+位运算

codeforces1364 D. Ehab's Last Corollary(最小环)

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

Codeforces Round #649 (Div. 2) D - Ehab's Last Corollary dfs