【BZOJ】1051 [HAOI2006]受欢迎的牛 强联通分量

110 篇文章 0 订阅
5 篇文章 0 订阅

其实本不想发这题的题解的,但是为了提醒自己不再犯错,还是发一波吧。
这题依旧是比较水的强联通分量,只要求所有出度为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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值