[强联通分量_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;

}

你可能感兴趣的:(DFS)