【HZOJ/Tarjan】#B.受欢迎的牛
作者:互联网
题目描述
每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头 牛被所有的牛认为是受欢迎的。
输入格式
第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可 能出现多个A,B)
输出格式
一个数,即有多少头牛被所有的牛认为是受欢迎的。
样例
样例输入
3 3
1 2
2 1
2 3
样例输出
1
数据范围与提示
10%的数据N<=20, M<=50
30%的数据N<=1000,M<=20000
70%的数据N<=5000,M<=50000
100%的数据N<=10000,M<=50000
#include<stdio.h> #include<stack> namespace bikuhiku{ template <typename _T> _T gtr(_T &_compare_x,_T &_compare_y) { return _compare_x > _compare_y ? _compare_x : _compare_y; } template <typename _T> _T les(_T &_compare_x,_T &_compare_y) { return _compare_x < _compare_y ? _compare_x : _compare_y; } template <typename _T> void get_int(_T &_data_x) { int _signal = 1; char _get_c; _data_x = 0; for(_get_c = getchar();_get_c < '0'||_get_c > '9';_get_c = getchar()) if(_get_c == '-') _signal = -1; for(;_get_c >= '0'&&_get_c <= '9';_get_c = getchar()) _data_x = (_data_x<<3)+(_data_x<<1)+(_get_c^48); _data_x *= _signal; return; } template <typename _T> void put_int(_T _data_x) { if(_data_x > 9) put_int(_data_x/10); putchar((_data_x%10)^48); return; } const int _ = 0; const int _Use = 1; }//申请一块命名空间; using namespace bikuhiku; using namespace std; const int z = 16384-4096-2048; int m, n, ans; int s, e; struct line{ int t, next; } edge[z*5]; int cnt, head[z], od[z]; void adline(int &f,int &t) { edge[++cnt].next = head[f]; edge[cnt].t = t; head[f] = cnt; return; } stack<int> stk; int dfn[z], low[z], time; int belong[z], num[z]; bool instk[z]; void tarjan(int &u) { dfn[u] = low[u] = ++time; stk.push(u); instk[u] = true; for(int i = head[u];i;i = edge[i].next) { if(!dfn[edge[i].t]) {//是树枝边; tarjan(edge[i].t); low[u] = les(low[u],low[edge[i].t]); } else if(instk[edge[i].t]) {//是返祖边; low[u] = les(low[u],dfn[edge[i].t]); } } if(low[u] == dfn[u]) {//构成强连通分量; int tmp; ++belong[0]; do { tmp = stk.top(); stk.pop(); instk[tmp] = false; belong[tmp] = belong[0]; ++num[belong[0]]; } while(tmp != u); } return; } int main() { get_int(n); get_int(m); for(int i = 1;i <= m;++i) { get_int(s); get_int(e); adline(s,e); } for(int i = 1;i <= n;++i) if(!dfn[i]) tarjan(i); for(int u = 1;u <= n;++u) for(int i = head[u];i;i = edge[i].next) if(belong[u] != belong[edge[i].t]) od[belong[u]]++;//使某个强连通分量的出度增加; for(int i = 1;i <= belong[0];++i) if(!od[i]) {//如果出度为零; if(ans) { putchar('0');//若存在两个出度为零的强连通分量,不存在受欢迎的牛; return 0; } else { ans = i;//记录下这个强连通分量的编号; } } put_int(num[ans]); return 0^_^0; }
标签:Tarjan,get,int,compare,edge,HZOJ,受欢迎,low 来源: https://www.cnblogs.com/bikuhiku/p/HZOJ_Tarjan_B-welcomecow.html