zoukankan      html  css  js  c++  java
  • 算法概论习题1001Forest

    题目意思,一个有向图,若有环(不仅仅是自环)或某个点入度大于等于2则不合法,否则合法,输出深度和所有连通分量在同一层的最大节点数。
    判断一个没有入度>=2有向图是否有环:
    只需一个判断条件:对所有入度为0的点进行DFS,若所有的点都访问到了,则无环,否则有环
    也就是说,只要保证每个点入度≥2,则该图的连通分量只能有几种情况:孤立点,非环,全部点收尾相接形成的环(不存在入度为0的点)
    所以对入度为0的点进行DFS前两种情况必定能访问到该连通分量内所有的点。

    http://soj.me/show_problem.php?pid=1001&cid=970

    #include <iostream>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define Max 10000
    int n, m, vis[Max], layer[Max], in[Max];
    
    vector<int> v[Max];
    
    bool valid;
    
    void dfs(int x, int l)
    {           
        vis[x] = 1;
        
        layer[l]++;
            
        for (int i = 0; i < v[x].size(); ++i)
            dfs(v[x][i], l+1);
    }
    
    int main()
    {   
        while (cin >> n >> m, n)
        {   
            valid = 1;
            
            memset(vis, 0, sizeof(vis));
            
            memset(in, 0, sizeof(in));
            
            memset(layer, 0, sizeof(layer));
            
            memset(v, 0, sizeof(v));
                
            int a, b;
            for (int i = 0; i < m; ++i)
            {
                cin >> a >> b;
                
                v[a].push_back(b);
                
                in[b]++;
                
                if (in[b] >= 2)
                {
                    valid = 0;
                }
            }
            //入度≥2的点的INVALID 
            if (!valid)
            {
                cout << "INVALID" << endl;
                
                continue;
            }        
            //对所有入度为0的点进行深搜 
            for (int i = 1; i <= n; ++i)
                if (in[i] == 0)   
                    dfs(i, 0);
            
            //若没有遍历所有的点则有环 
            for (int i = 1; i <= n; ++i)
            {
                if (!vis[i])
                {
                    valid = 0;
                    
                    break;
                }
            }
            //DFS没有遍历所有的点的INVALID 
            if (!valid)
            {
                cout << "INVALID" << endl;
                
                continue;
            }
            //depth的值就是layer[i]不为0的i值中最大的那个 
            int depth = -1;
            for (int i = 0; i < n; ++i)
            {
                if (layer[i])
                    depth++;
            }
            cout << depth << ' ' << *max_element(layer,layer+n) << endl;
        }
    }                                 
  • 相关阅读:
    获取发布的头条的url,避免点击打开新的页面
    下载图片 保存至本地 返回路径
    线程运行的3个状态
    程序并发执行所需付出的时空开销
    web metrics dashboard 数据分析工具 看板 从可视化发现问题 避免sql重复写 调高效率
    Binary safe
    simple dynamic string
    a
    a
    从业务角度 减少代码执行的时间 和 因长时间执行的而带来的代码复杂性 日志恢复数据
  • 原文地址:https://www.cnblogs.com/chenyg32/p/3017924.html
Copyright © 2011-2022 走看看