F. Ehab's Last Theorem ( DFS树 )

题目链接:https://codeforces.com/contest/1325/problem/F

CF上有一篇讲 DFS 树的博客讲的挺好的,mark一下 https://codeforces.com/blog/entry/68138

想法:

在这张图里面,粗的边就是树边,细的边就是非树边。

这里我们就要用到dfs树一个及其重要的性质:

一条非树边连接了一个点和它在生成树中的一个后代

#pragma GCC optimize(3,"Ofast","inline")//O3优化
#pragma GCC optimize(2)//O2优化
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>
#include <cstring>

#define LL long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)

const double eps = 1e-10;
const int maxn = 2e5 + 10;
const int mod = 1e9 + 7;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

struct edge {
    int v,nxt;
}e[maxn << 1];

int head[maxn];
int cnt;
int sq;
int dep[maxn],tag[maxn];
vector<int> vec,ans;

inline void add_edge(int u,int v) {
    e[++cnt].v = v;
    e[cnt].nxt = head[u];
    head[u] = cnt;
}

void dfs(int x) {
    vec.push_back(x);
    dep[x] = vec.size();
    for (int i = head[x];~i;i = e[i].nxt) {
        int v = e[i].v;
        if (!dep[v])
            dfs(v);
        else if (dep[x]-dep[v] >= sq-1) {
            cout << 2 << endl;
            cout << dep[x]-dep[v]+1 << endl;
            for (int j = dep[v]-1;j < dep[x];j++)
                cout << vec[j] << " ";
            cout << endl;
            exit(0);
        }
    }
    if (!tag[x]) {
        ans.push_back(x);
        for (int i = head[x];~i;i = e[i].nxt) {
            int v = e[i].v;
            tag[v] = 1;
        }
    }
    vec.pop_back();
}

int main() {
    ios::sync_with_stdio(0);
    int n,m;
    cin >> n >> m;
    memset(head,-1, sizeof(head));
    cnt = 0;
    for (int i = 1;i <= m;i++) {
        int u,v;
        cin >> u >> v;
        add_edge(u,v);
        add_edge(v,u);
    }
    sq = sqrt(n-1) + 1;
    dfs(1);
    cout << 1 << endl;
    for (int i = 0;i < sq;i++)
        cout << ans[i] << " ";
    cout << endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/-Ackerman/p/12585072.html