就是已知每个点的度数至少为k,要求在图中找一个环,长度为k。这个题可以用最长路的方法去思考,假设图中一条最长路,包含v1,v2,...vn,那么对于vn,它的所有相邻的点一定都被包含在这条最长路中,否则这个点接在vn后面,就是一条更长的路。那么对于vn,找到它所有相邻的点中在这条最长路里离它最远的点vl,因为vn度数为k,所以vl到vn至少有n+1个点,且首尾相连够成一个环。这样就可以从任意一个点,例如1开始搜一个长度大于k的环即可,因为即使一个图是有多个块的,每个块中都至少存在一个长度为k的环。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
using namespace std;
typedef long long LL;
const int maxn = 100000 + 5;
vector<int> G[maxn];
int fa[maxn];
int vis[maxn];
int chuo[maxn];
int k,tag;
void dfs(int x,int cnt){
for(int i = 0;i < G[x].size();i++){
if(tag == 1) return;
int u = G[x][i];
if(!vis[u]){
vis[u] = 1;
fa[u] = x;
chuo[u] = cnt+1;
dfs(u,cnt+1);
vis[u] = 0;
}
else if(chuo[x]-chuo[u] >= k){
cout << chuo[x]-chuo[u] + 1 << endl;
int tem = x;
cout << x << ' ';
while(fa[tem] != u){
cout << fa[tem] << ' ';
tem = fa[tem];
}
cout << u << endl;
tag = 1;
return;
}
}
}
int main(){
int n,m;
while(cin >> n >> m >> k){
for(int i = 1;i <= n;i++) G[i].clear();
while(m--){
int x,y;
cin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
memset(vis,0,sizeof(vis));
vis[1] = 1;
chuo[1] = 0;
tag = 0;
dfs(1,0);
}
return 0;
}