Codeforces Round #161 (Div. 2) D. Cycle in Graph(无向图中找指定长度的简单环)

来源:互联网 发布:网络教育本科第二学历 编辑:程序博客网 时间:2024/05/01 18:40

题目链接:http://codeforces.com/problemset/problem/263/D

思路:一遍dfs即可,dp[u]表示当前遍历到节点u的长度,对于节点u的邻接点v,如果v没有被访问过,则继续访问,否则计算dp[u] - dp[v] + 1是否大于等于K + 1,如果是,就说明找到了这样一个符合要求的环,然后将回退,回退的时候将环上的节点标记即可,否则,就继续找。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <deque>#define REP(i, a, b) for (int i = (a); i < (b); ++i)#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)using namespace std;const int MAX_N = (100000 + 10);int N, M, K, st, found, flag[MAX_N], vis[MAX_N], dp[MAX_N];vector<int > g[MAX_N];vector<int > ans;void dfs(int u, int father, int len){    vis[u] = 1;    dp[u] = len;    REP(i, 0, (int)g[u].size()) {        int v = g[u][i];        if (v == father) continue;        if (vis[v] && dp[u] - dp[v] + 1 >= K + 1) {            st = v;            flag[u] = 1;            ans.push_back(u);            return;        }        if (!vis[v]) dfs(v, u, len + 1);        if (st) {            if (found) return;            if (u == st) found = 1;            ans.push_back(u);            flag[u] = 1;            return;        }    }}int main(){    while (cin >> N >> M >> K) {        ans.clear();        FOR(i, 1, N) flag[i] = vis[i] = 0, g[i].clear();        while (M--) {            int u, v; cin >> u >> v;            g[u].push_back(v);            g[v].push_back(u);        }        st = found = 0;        dfs(1, -1, 0);        cout << (int)ans.size() << endl;        REP(i, 0, (int)ans.size()) {            if (i == (int)ans.size() - 1) cout << ans[i] << endl;            else cout << ans[i] << ' ';        }    }    return 0;}


0 0
原创粉丝点击