# BZOJ1051 [HAOI2006]受欢迎的牛 强连通分量缩点

## BZOJ1051 [HAOI2006]受欢迎的牛

[HAOI2006]受欢迎的牛 の 传送门

Description

Input

Output

Sample Input
3 3
1 2
2 1
2 3

Sample Output
1

「数据范围」
10%的数据N<=20, M<=50
30%的数据N<=1000,M<=20000
70%的数据N<=5000,M<=50000
100%的数据N<=10000,M<=50000

tarjan强连通分量缩点模板题

Code

//bzoj1051
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;

const int N = 10007, M = 50007;
int n, m, cnt, scc, tim, ans, head[N], to[M], nxt[M], low[N], dfn[N], belong[N], vis[N], hav[N], chu[N];
stack <int> S;

int ans = 0, f = 1;
char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar())
if (ch == '-')
f = 0;
for(; ch >= '0' && ch <= '9'; ch = getchar())
ans = (ans << 3) + (ans << 1) + ch - 48;
return f? ans: -ans;
}
void tarjan(int u){
dfn[u] = low[u] = ++tim;
S.push(u);
vis[u] = 1;
int v;
for (int i = head[u]; i; i = nxt[i]){
v = to[i];
if (!dfn[v])
tarjan(v), low[u] = min(low[u], low[v]);
else
if (vis[v])
low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u]){
scc++;
do {
v = S.top();
vis[v] = 0;
belong[v] = scc;
hav[scc]++;
S.pop();
} while(u != v);
}
}
int main(){
tim = cnt = scc = 0;
while (S.size())
S.pop();
for (register int i = 1; i <= m; ++i){
}
for (register int i = 1; i <= n; ++i)
if (!dfn[i]) tarjan(i);
for (register int k = 1; k <= n; ++k)
for (int i = head[k]; i; i = nxt[i]){
int v = to[i];
if (belong[k] != belong[v])
chu[belong[k]]++;
}
ans = 0;
for (int i = 1; i <= scc; ++i){
if (!chu[i])
if (ans){
printf("0\n");
return 0;
}
else
ans = hav[i];
}
printf("%d\n", ans);
return 0;
}

posted @ 2019-01-29 13:45  DorkyTAT  阅读(167)  评论(2编辑  收藏