Codeforces Round 649 (Rated for Div. 2)D. Ehab s Last Corollary (图论+简单环)

https://codeforces.ml/contest/1364/problem/D

/*
给出一张 n 个点的无向连通图和一个常数 k。
你需要解决以下两个问题的任何一个:
1. 找出一个大小为 k/2 (向上取整)的独立集。
2. 找出一个大小不超过 k 的环。
独立集是一个点的集合,满足其中任意两点之间在原图上没有边直接相连。
3≤k≤n≤105,n?1≤m≤2×105

其实就是找出无向图中的简单环(不含重边,环内部非相邻点之间没有边)
你找到一个长度大于k的环,直接取不相邻的间隔点按情况1处理即可。
找到长度小于k的环,直接可作为结果按情况2输出。
没找到简单环的情况,就说明这是一颗树,按深度奇偶性分成两部分,取元素多的那一部分按情况一处理。
*/
#include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define rush! ios::sync_with_stdio(false);cin.tie(0);
const int inf = 0x3f3f3f3f;
const long long linf = 0x3f3f3f3f3f3f3f3f;
vector<int >g[200005];
typedef long long ll;
const int N=200005;
int ind;
int dfn[N],fa[N];
int loop[N],cnt;
int vis[N];
int huan;    
ll t1=0;
ll t2=0;
queue<int >q1;
queue<int >q2;
void loops(int u){
    dfn[u]=++ind;
    for(auto i:g[u]){
        if(i==fa[u])continue;
        if(dfn[i]){
            if(dfn[i]<dfn[u])continue;
            loop[++cnt]=i;
            vis[i]=1;
            for(;i!=u;i=fa[i]){
                loop[++cnt]=fa[i];
                vis[fa[i]]=1;
            }
            if(!huan)
                huan=cnt;
            return ;
        }
        else{
            fa[i]=u;
            loops(i);
            if(huan)return ;
        }
    }
}
void dfs(int u,int fa,int ceng){
    if(ceng%2){
        q1.push(u);
        t1++;
    }
    else{
        t2++;
        q2.push(u);
    }
    for(auto i:g[u]){
        if(i!=fa){
            dfs(i,u,ceng+1);
        }
    }
}
void solve(){
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
        ind=0;
        dfn[i]=0,fa[i]=0;
        loop[i]=0;
        cnt=0;
        vis[i]=0;
        g[i].clear();
    }
    for(int i=1;i<=m;i++){
        int x,y;
         cin>>x>>y;
         g[x].push_back(y);
         g[y].push_back(x);
    }
    ll ans=0;
    loops(1);
    if(huan<=k&&huan){
        cout<<2<<endl;
        cout<<huan<<endl;
           for(int i=1;i<=huan;i++){
               cout<<loop[i]<<" ";
        }
    }
    else if(huan==0){
        cout<<1<<endl;
        dfs(1,-1,1);
        int f=0;
        if(t1>t2){
            while(f<(k-1)/2+1){
                f++;
                cout<<q1.front()<<" ";
                q1.pop();
            }
        }
        else{
            while(f<(k-1)/2+1){
                f++;
                cout<<q2.front()<<" ";
                q2.pop();
            }
        }
    }
    else{
        cout<<1<<endl;
        int cnt=0;
        int f=0;
        for(int i=1;i<=huan;i++){
            if(i%2){
                f++;
                cout<<loop[i]<<" ";
            }
            if(f==(k-1)/2+1)break;
        }
    } 
    cout<<endl;
}
int main(){
    int t=1;
    //cin>>t;
//   cout<<C(5,2);
    while(t--){
        solve();
    }
}

 

posted @ 2021-01-13 17:06  _LH2000  阅读(103)  评论(0编辑  收藏  举报