《CF1325F Ehab's Last Theorem》

题目的输出就把我搞炸了。。没仔细看输出就一直写了,结果。。

首先要求的独立集是恰好个,然后环的输出要输出环上的点数。

首先考虑建立图上的dfs树,对于环,很显然我们考虑每条非树边,然后在环的树边一侧的条数就可以用两个点的深度来处理一下。

对于独立集合的情况,可以染色处理,但是因为dfs树叶子节点一定互相独立,所以我们尽可能多放叶子独立集的大小就会尽可能大。

所以我们染色的时候要从叶子开始染色。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int M = 2e5 + 5;
#define INF 1e9
typedef long long LL;
#define dbg(ax) cout << "now num is " << ax << endl;

int n,m;
vector<int> G[N];
int dfn[N],tim = 0;
int dep[N],ma,f = 0,ffa[N];
vector<int> ans,ans2;
bool vis[N];
void dfs1(int u,int fa) {
    dfn[u] = ++tim;
    ffa[u] = fa;
    dep[u] = dep[fa] + 1;
    for(auto v : G[u]) {
        if(!dfn[v]) dfs1(v,u);
        else {
            if(dep[u] - dep[v] >= ma - 1) {
                int st = u;
                while(st != v) {
                    ans2.push_back(st);
                    st = ffa[st];
                }
                ans2.push_back(v);
                printf("2\n");
                printf("%d\n",ans2.size());
                for(auto v : ans2) printf("%d ",v);
                exit(0);
            }
        }
    }
    if(!vis[u]) {
        for(auto v : G[u]) vis[v] = 1;
    }
}
void solve() {
    scanf("%d %d",&n,&m);
    ma = ceil(sqrt(n * 1.0));
    while(m--) {
        int u,v;scanf("%d %d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs1(1,0);
    for(int i = 1;i <= n;++i) {
        if(!vis[i]) ans.push_back(i);
        if(ans.size() == ma) break;
    }
    printf("1\n");
    for(auto v : ans) printf("%d ",v);
}
int main() {
    solve();
    system("pause");
}

/*
5 4
1 2
2 3
3 4
4 5

9 12
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
1 3
2 4
5 7
6 8

*/
View Code

 

posted @ 2021-11-22 20:05  levill  阅读(21)  评论(0编辑  收藏  举报