• 发现环


    问题描述
      小明的实验室有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

    拓扑排序

    无向图拓扑排序一遍然后输出度为4的所有结点

    #include<iostream>
    #include<cstring>
    
    using namespace std;
    
    const int N = 100010, M = 200010;
    
    int h[N], e[M], ne[M], idx;
    int n;
    int w[N];
    int q[M], hh, tt = -1;
    
    void topsort(){
        for(int i = 1; i <= n; i ++)
            if(w[i] == 2) q[++ tt] = i;
            
        while(hh <= tt){
            int t = q[hh ++];
            for(int i = h[t]; ~i; i = ne[i]){
                int j = e[i];
                w[j] -= 2;
                if(w[j] == 2) q[++ tt] = j;
            }
        }
    }
    
    void add(int a, int b){
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
        w[a] ++;
        w[b] ++;
    }
    
    int main(){
        memset(h, -1, sizeof h);
        
        cin >> n;
        
        for(int i = 0; i < n; i ++){
            int a, b;
            cin >> a >> b;
            add(a, b);
            add(b, a);
        }
        
        topsort();
        
        for(int i = 1; i <= n; i ++)
            if(w[i] == 4) cout << i << ' ';
        
        return 0;
    }
    

    并查集判断环,dfs得结果

    在输入边的时候往并查集里面加边ab,如果两个结点ab已经在一个集合里面,那么说明加了这条边以后出现了环,所以可以设置a为起点,b为终点然后dfs一遍即可,注意要走a到b的较长的一条路,否则就只有ab了

    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    
    using namespace std;
    
    const int N = 100010, M = 200010;
    
    int h[N], e[M], ne[M], idx;
    int n;
    int start, aim;
    int p[N];
    vector<int> res;
    int st[N];
    
    struct{
        int a, b;
    }edges[N];
    
    int find(int x){
        if(x != p[x]) p[x] = find(p[x]);
        return p[x];
    }
    
    void add(int a, int b){
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    }
    
    int dfs(int u){
        res.push_back(u);
        st[u] = 1;
        if(u == aim) return 1;
        
        for(int i = h[u]; i != -1; i = ne[i]){
            int j = e[i];
            if(st[j] == 0){
                if(u == start && j == aim) continue;
                if(dfs(j)) return 1;
                res.pop_back();
                st[j] = 0;
            }
        }
        return 0;
    }
    
    int main(){
        memset(h, -1, sizeof h);
        
        cin >> n;
        
        for(int i = 1; i <= n; i ++) p[i] = i;
        
        for(int i = 0; i < n; i ++){
            int a, b;
            cin >> a >> b;
            
            add(a, b);
            add(b, a);
            
            int x = find(a), y = find(b);
            if(x == y)
                start = a, aim = b;
            else p[x] = y;
        }
    
        dfs(start);
        
        sort(res.begin(), res.end());
        
        for(int i = 0; i < res.size(); i ++) cout << res[i] << ' ';
        
        return 0;
    }
    
  • 相关阅读:
    spark on yarn 无法提交任务问题
    git rebase 操作撤销
    vim 删除屏蔽行
    mysql 登录远程数据库 失败
    springboot拦截器中获取配置文件值
    根据经纬度获取地址 :位置名称 区 市 省 国家 邮编
    element-ui upload组件上传
    java读写excel文件( POI解析Excel)
    easyui+themeleaf 分页查询实现
    java生成二维码
  • 原文地址:https://www.cnblogs.com/tomori/p/13711144.html
Copyright © 2020-2023  润新知