其实本不想发这题的题解的,但是为了提醒自己不再犯错,还是发一波吧。
这题依旧是比较水的强联通分量,只要求所有出度为0的强联通分量的节点数总和就行了。
按理来说,我应该是比较轻松的就会过掉的……
但是!
因为自己的粗心,忘了考虑有多个强联通分量出度为0……
于是,WA了好几次……
好吧,无论做什么题目,不管有多么简单,都应该认真对待,狮子搏兔亦用全力!
附上AC代码:
#include <cstdio>
#include <cstring>
#include <stack>
#define N 10010
using namespace std;
stack <int> s;
struct note{
int to,nt;
}side[50010];
int n,m,x,y,num,h[N],b[N],t[N],d[N],sy[N],rd[N],cd[N],size,g,ans,sum[N];
void add(int x,int y){side[++num].to=y,side[num].nt=h[x],h[x]=num;}
void so(int x){
b[x]=1,t[x]=d[x]=++size,s.push(x);
for (int i=h[x]; ~i; i=side[i].nt)
if (!d[side[i].to]) so(side[i].to),t[x]=min(t[x],t[side[i].to]);
else if (b[side[i].to]) t[x]=min(t[x],d[side[i].to]);
if (t[x]==d[x]){
++g;
while (1){
int p=s.top();s.pop(),b[p]=0,sy[p]=g,++sum[g];
if (p==x) break;
}
}
return;
}
int main(void){
scanf("%d%d",&n,&m),memset(h,-1,sizeof h);
for (int i=1; i<=m; ++i) scanf("%d%d",&x,&y),add(x,y);
for (int i=1; i<=n; ++i) if (!d[i]) so(i);
for (int i=1; i<=n; ++i)
for (int j=h[i]; ~j; j=side[j].nt)
if (sy[i]!=sy[side[j].to]) ++cd[sy[i]],++rd[sy[side[j].to]];
for (int i=1; i<=g; ++i)
if (!cd[i]) {
if (ans>0) {
printf("0");
goto Z;
}
ans+=sum[i];
}
printf("%d",ans);
Z: return 0;
}