zoukankan      html  css  js  c++  java
  • 发现环

    问题描述
      小明的实验室有N台电脑,编号1~N。原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。


      不过在最近一次维护网络时,管理员误操作使得某两台电脑之间增加了一条数据链接,于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径,使得这些电脑上的数据传输出现了BUG。


      为了恢复正常传输。小明需要找到所有在环路上的电脑,你能帮助他吗?
    输入格式
      第一行包含一个整数N。
      以下N行每行两个整数a和b,表示a和b之间有一条数据链接相连。


      对于30%的数据,1 <= N <= 1000
      对于100%的数据, 1 <= N <= 100000, 1 <= a, b <= N


      输入保证合法。
    输出格式
      按从小到大的顺序输出在环路上的电脑的编号,中间由一个空格分隔。
    样例输入
    5
    1 2
    3 1
    2 4
    2 5
    5 3
    样例输出
    1 2 3 5
     
    深搜,遇到一个点不是自己的前驱却已经访问过且与当前点相邻,那么就是从这个点到当前点这条链上的点,记录下来排序输出。
    代码:
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    vector<int> s[100001];
    int f[100001] = {-1};
    int e[100001];
    int n,a,b,flag = 0,c;
    void get(int k)
    {
        while(k != -1)
        {
            e[c ++] = k;
            k = f[k];
        }
    }
    void dfs(int k)
    {
        for(int i = 0;i < s[k].size();i ++)
        {
            if(flag == -1)return;
            if(f[k] == s[k][i])continue;
            if(f[s[k][i]])
            {
                f[s[k][i]] = -1;
                flag = -1;
                get(k);
                return;
            }
            f[s[k][i]] = k;
            dfs(s[k][i]);
            f[s[k][i]] = 0;
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i = 0;i < n;i ++)
        {
            scanf("%d%d",&a,&b);
            s[a].push_back(b);
            s[b].push_back(a);
        }
        dfs(1);
        sort(e,e + c);
        if(e)printf("%d",e[0]);
        for(int i = 1;i < c;i ++)
        {
            printf(" %d",e[i]);
        }
    }

     2019重做,思路相同。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    vector<int> e[100001],tans,ans;
    int vis[100001];
    void dfs(int k) {
        for(int i = 0;i < e[k].size();i ++) {
            if(!ans.empty()) return;
            if(vis[e[k][i]] && vis[e[k][i]] == tans.size() - 2) continue;
            if(vis[e[k][i]]) {
                for(int j = vis[e[k][i]];j < tans.size();j ++) {
                    ans.push_back(tans[j]);
                }
                return;
            }
            vis[e[k][i]] = tans.size();
            tans.push_back(e[k][i]);
            dfs(e[k][i]);
            tans.pop_back();
            vis[e[k][i]] = 0;
        }
    }
    int main() {
        int n,a,b;
        scanf("%d",&n);
        for(int i = 0;i < n;i ++) {
            scanf("%d%d",&a,&b);
            e[a].push_back(b);
            e[b].push_back(a);
        }
        dfs(1);
        sort(ans.begin(),ans.end());
        for(int i = 0;i < ans.size();i ++) {
            if(i) putchar(' ');
            printf("%d",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    HLG 1522 子序列的和【队列的应用】
    POJ 3273 Monthly Expense【二分】
    HDU 4004 The Frog's Games 【二分】
    POJ 2001 Shortest Prefixes【第一棵字典树】
    POJ 2823 Sliding Window【单调对列经典题目】
    HDU 1969 Pie 【二分】
    POJ 3125 Printer Queue【暴力模拟】
    POJ 3250 Bad Hair Day【单调栈】
    字典树【模板】
    验证码 Code
  • 原文地址:https://www.cnblogs.com/8023spz/p/9068152.html
Copyright © 2011-2022 走看看