就是已知每個點的度數至少為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;}