bzoj 1051 强连通分量,tarjan缩点
tags: 要受所有牛欢迎,也就是只能有一个强连通。 tarjan缩点后,求出度为0的点即是。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a;i<=b;i++) #define per(i,b,a) for (int i=b;i>=a;i--) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 5e5+10; struct Edge{ int u, v, next; }e[N<<1]; int n, m, tot, top, ans, sum, num; int Stack[N<<2], dfn[N], low[N], Belong[N], sz[N], out[N], head[N]; bool instack[N]; void Addedge(int u, int v) { e[++tot].u=u, e[tot].v=v, e[tot].next=head[u], head[u]=tot; } void Tarjan(int u) { dfn[u]=low[u]=++tot; Stack[top++]=u, instack[u]=1; for(int i=head[u]; i; i=e[i].next) { int v=e[i].v; if(dfn[v]==0) { Tarjan(v); low[u]=min(low[u], low[v]); } else if(instack[v]) low[u]=min(low[u], dfn[v]); } if(dfn[u]==low[u]) { sum++; while(top!=0) { int en=Stack[--top]; instack[en]=0; Belong[en]=sum; sz[sum]++; if(en==u) break; } } } int main() { scanf("%d %d", &n, &m); int u, v; rep(i,1,m) { scanf("%d %d", &u, &v); Addedge(u, v); } rep(i,1,n) if(dfn[i]==0) Tarjan(i); rep(i,1,m) { u=Belong[e[i].u], v=Belong[e[i].v]; if(u!=v) out[u]++; } rep(i,1,sum) if(out[i]==0) ans=sz[i], num++; printf("%d\n", num==1?ans:0); return 0; }