Description
Input
Output
Sample Input
5
2 4 3 0
4 5 0
0
0
1 0
Sample Output
1
2
                        
题意:有n个学校,学校之间可以传递信息,为单向传递。
问题一:至少要向几个学校传递原始信息,才能保证所有学校都能收到信息。
<span style="font-size:18px;">#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const double PI = acos(-1.0);
const double e = 2.718281828459;
const double eps = 1e-8;
const int MAXN = 110;
int n;
struct Edge
{
    int v;
    int w;
    int next;
} edge[MAXN*MAXN];
struct shrink_point
{
    int in;
    int out;
    int num;
} sp[MAXN];
int head[MAXN];
int instack[MAXN];
int scc[MAXN];
int LOW[MAXN];
int DFN[MAXN];
stack<int>Q;
int Index, edge_cnt, scc_cnt;
void addedge(int u, int v)
{
    edge[edge_cnt].v = v;
    edge[edge_cnt].next = head[u];
    head[u] = edge_cnt++;
}
void Tarjan(int u)
{
    LOW[u] = DFN[u] = ++Index;
    instack[u] = 1;
    Q.push(u);
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].v;
        if(!DFN[v])
        {
            Tarjan(v);
            if(LOW[u] > LOW[v])
                LOW[u] = LOW[v];
        }
        else if(instack[v] && LOW[u]>DFN[v])
            LOW[u] = DFN[v];
    }
    if(LOW[u] == DFN[u])
    {
        int j;
        scc_cnt++;
        do
        {
            j = Q.top();
            Q.pop();
            instack[j] = 0;
            scc[j] = scc_cnt;
            sp[scc_cnt].num++;
        }
        while(j != u);
    }
}
void solve()
{
    memset(LOW, 0, sizeof(LOW));
    memset(DFN, 0, sizeof(DFN));
    memset(instack, 0, sizeof(instack));
    memset(sp, 0, sizeof(sp));
    while(!Q.empty())
        Q.pop();
    Index = scc_cnt = 0;
    for(int i = 1; i <= n; i++)
        if(!DFN[i])
            Tarjan(i);
    for(int i = 1; i <= n; i++)
        for(int k = head[i]; k != -1; k = edge[k].next)
        {
            int j = edge[k].v;
            if(scc[i] != scc[j])
            {
                sp[scc[i]].out++;
                sp[scc[j]].in++;
            }
        }
    if(scc_cnt == 1)
    {
        printf("%d\n%d\n", 1, 0);
        return;
    }
    int num1 = 0;
    int num2 = 0;
    for(int i = 1; i <= scc_cnt; i++)
    {
        if(sp[i].out == 0)
            num1++;
        if(sp[i].in == 0)
            num2++;
    }
    //printf("%d %d\n", num1, num2);
    printf("%d\n%d\n", num2, max(num1, num2));
}
int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    while(cin>>n)
    {
        int v;
        edge_cnt = 0;
        memset(head, -1, sizeof(head));
        memset(edge, 0, sizeof(edge));
        for(int i = 1; i <= n; i++)
        {
            while(cin>>v&&v)
            {
                addedge(i, v);
            }
        }
//        for(int i = 1; i <= n; i++)
//        {
//            printf("%d", i);
//            for(int k = head[i]; k != -1; k = edge[k].next)
//            {
//                printf(" %d", edge[k].v);
//            }
//            printf("\n");
//        }
        solve();
    }
    return 0;
}
</span>
POJ 1236 - Network of Schools(强连通分量)
原文地址:http://blog.csdn.net/u014028317/article/details/45605371