• [强联通分量_DFS] 0725


    N个学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输。
    问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。
    问题2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。

    input format:
    输入有多组样例,大约1000组。
    每组样例第一行包含两个整数N,M(2<=N<=100),N代表学校的个数,M代表边的个数(M<N*N)
    接下来M行,每行包含连个整数u,v,代表u可以向v单向发送数据。

    output format
    每组样例对应两行,分别是问题一和问题二的解。

    sample input
    7 8
    1 2
    2 3
    3 1
    1 4
    4 5
    5 6
    6 4
    7 6

    sample output
    2
    2

    ----------------------------------------------------------------------------------

    所需发放软件的数量为缩点后入度为0的点的个数,所需添加的边为入度为0和出度为0点的个数的较大者。

    ----------------------------------------------------------------------------------

    # include <cstdio>
    # include <cstring>
    
    # define N 100 + 5
    
    int n, m;
    int t, cols;
    int f[N], c[N], in[N], out[N];
    char vis[N], g[N][N];
    
    void read_graph(void)
    {
        int u, v;
        for (int i = 1; i <= n; ++i)
        {
            in[i] = 0;
            memset(g[i]+1, 0, sizeof(int)*n);
        }
        for (int i = 1; i <= m; ++i)
        {
            scanf("%d%d", &u, &v);
            g[u][v] = 1;
        }
    }
    
    void dfs(int u)
    {
        vis[u] = 1;
        for (int v = 1; v <= n; ++v) if (!vis[v] && g[u][v])
            dfs(v);
        f[++t] = u;
    }
    
    void rdfs(int u)
    {
        vis[u] = 1;
        c[u] = cols;
        for (int v = 1; v <= n; ++v) if (!vis[v] && g[v][u])
            rdfs(v);
    }
    
    void solve(void)
    {
        t = 0;
        memset(vis+1, 0, sizeof(char)*n);
        for (int i = 1; i <= n; ++i) if (!vis[i]) dfs(i);
        cols = 0;
        memset(vis+1, 0, sizeof(char)*n);
        for (int i = n; i >= 1; --i) if (!vis[f[i]]) ++cols, rdfs(f[i]);
        if (cols == 1) {printf("1\n0\n"); return ;}
        memset(in+1,  0, sizeof(int)*cols);
        memset(out+1, 0, sizeof(int)*cols);
        for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
        {
            if(g[i][j] && c[i] != c[j])
            {
                ++in[c[j]];
                ++out[c[i]];
            }
        }
        int zin = 0, zout = 0;
        for (int i = 1; i <= cols; ++i)
        {
            if (in[i]  == 0) ++zin;
            if (out[i] == 0) ++zout;
        }
        printf("%d\n%d\n", zin, zin>zout ? zin:zout);
    }
    
    
    int main()
    {    
        while (~scanf("%d%d", &n, &m))
        {
            read_graph();
            solve();
        }
        
        return 0;
    }
  • 相关阅读:
    LED点阵书写显示
    cpld fpga 区别
    SublimeText 自带格式化代码功能
    iText C# 合并PDF文件流,以及A5变A4时内容默认放在最底下的问题的解决方法;ASP.NET 实现Base64文件流下载PDF
    Adobe Acrobat 9 Pro序列号
    c#比较两个数组的差异
    iNotify.js通知JS 实现浏览器的 title 闪烁、滚动、声音提示、chrome、Firefox、Safari等系统通知。
    配置IISExpress允许外部访问
    https://sweetalert2.github.io/
    c# 利用MailKit.IMap 收取163邮件
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2626079.html
Copyright © 2020-2023  润新知