题目链接: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; }