poj 1236_Network of Schools_强连通分量

来源:互联网 发布:全国网络电视在线直播 编辑:程序博客网 时间:2024/06/05 23:55

题目大意

N(2

思路

用tarjan求强连通分量后求每一个的出度和入度即可


#include <stdio.h>#include <string>#include <cstring>#include <stack>using namespace std;#define fill(x, y) sizeof(x, y, sizeof(x))#define maxn 101int n;struct edge{    int from, to, next;}e[maxn*50];int ls[maxn*50], dfn[maxn], low[maxn], belong[maxn], in[maxn], out[maxn];int dindex = 0, bcnt = 0;bool instack[maxn];stack<int> s;void tarjan(int x){    dindex++;    dfn[x] = dindex;    low[x] = dindex;    s.push(x);    instack[x] = 1;    for (int i = ls[x]; i; i = e[i].next)    {        int to = e[i].to;        if (dfn[to] == 0)        {            tarjan(to);            if (low[x] > low[to]) low[x] = low[to];        }        else        {            if (instack[to] && dfn[to] < low[x])                low[x] = dfn[to];        }    }    if (dfn[x] == low[x])    {        bcnt++;        int j;        do        {            j = s.top();            instack[j] = 0;            s.pop();            belong[j] = bcnt;        }        while(x != j);    }}void solve(){    while (! s.empty()) s.pop();    fill(dfn, 0);    for (int i = 1; i <= n; i++)        if (dfn[i] == 0) tarjan(i);}int main(){    while(~scanf("%d", &n))    {    int l = 0;    for (int i = 1; i <= n; i++)    {        int x;        while (scanf("%d", &x) && x != 0)        {            e[++l].from = i;            e[l].to = x;            e[l].next = ls[i];            ls[i] = l;        }     }    solve();    for (int i = 1; i <= l; i++)    {        if (belong[e[i].from] != belong[e[i].to])        {            out[belong[e[i].from]]++;            in[belong[e[i].to]]++;        }    }    int ans = 0;    for (int i = 1; i <= bcnt; i++)        if (in[i] == 0) ans++;    int ll = 0, rr = 0;    for (int i = 1; i <= bcnt; i++)    {        if (out[i] == 0) ll++;        if (in[i] == 0) rr++;    }    if (bcnt == 1) {printf("1\n0\n"); continue;}    printf("%d\n", ans);    printf("%d\n", ll > rr ? ll : rr);}}
原创粉丝点击