【NOIP模板】 tarjan

来源:互联网 发布:网络统考成绩查询短信 编辑:程序博客网 时间:2024/05/16 03:14
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;struct Edge {    int u, v, next;} edge[100010];int n, m, num = 0, in[100010], out[100010], head[100010];int top = 0, cnt = 0, index = 0, dfn[50010], low[50010], place[50010], stack[50010];void add(int u, int v) {    num ++;    edge[num].u = u;    edge[num].v = v;    edge[num].next = head[u];    head[u] = num;}void tarjan(int u) {    stack[++ top] = u;    dfn[u] = low[u] = ++ index;    for(int i = head[u]; i; i = edge[i].next) {        int v = edge[i].v;        if(! low[v]) {            tarjan(v);            low[u] = min(low[u], low[v]);        }           else if(! place[v]) low[u] = min(low[u], dfn[v]);    }    if(low[u] == dfn[u]) {        cnt ++;        while(1) {            int x = stack[top --];            place[x] = cnt;            if(x == u) break;        }    }}int main() {    scanf("%d", &n);    for(int i = 1; i <= n; i ++)        while(scanf("%d", &m) && m)            add(i, m);    for(int i = 1; i <= n; i ++)        if(! place[i]) tarjan(i);    if(cnt == 1) {        printf("1\n0");        return 0;    }    for(int i = 1; i <= num; i ++) {        int u = edge[i].u, v = edge[i].v;        if(place[u] != place[v])            in[place[v]] ++, out[place[u]] ++;    }    int ans1 = 0, ans2 = 0;    for(int i = 1; i <= cnt; i ++) {        if(! in[i]) ans1 ++;        if(! out[i]) ans2 ++;    }    printf("%d\n%d", ans1, max(ans1, ans2));    return 0;}
原创粉丝点击