codevs 2604 舞会邀请 tarjan

来源:互联网 发布:高晓松酒驾 知乎 编辑:程序博客网 时间:2024/05/16 11:38

题目:
http://codevs.cn/problem/2604/

数组开小了,WA了3个点;

并查集在codevs可以AC,但在洛谷上只有82分;
codevs真的要没落了吗?<-_<-

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<stack>using namespace std;const int MAXN=1000001;int fst[MAXN],nxt[MAXN];int ru[MAXN],low[MAXN],dfn[MAXN],scc[MAXN];int tim,tot,n,ans,cnt;stack<int>s;struct hh { int from,to; }ma[MAXN];void build(int f,int t){    ma[++tot]=(hh){f,t};    nxt[tot]=fst[f];    fst[f]=tot;}void tarjan(int x){    low[x]=dfn[x]=++tim;    s.push(x);    for(int i=fst[x];i;i=nxt[i])    {        int v=ma[i].to;        if(!dfn[v]) tarjan(v),low[x]=min(low[x],low[v]);        else if(!scc[v]) low[x]=min(low[x],dfn[v]);    }    if(low[x]==dfn[x])    {        cnt++;        while(1)        {            int u=s.top();            s.pop(),scc[u]=cnt;            if(u==x) return;        }    }    return;}void solve(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        int num=0;        while(1)        {            scanf("%d",&num);            if(!num) break;            build(i,num);        }    }    for(int i=1;i<=n;i++)        if(!dfn[i]) tarjan(i);    for(int i=1;i<=tot;i++)    {        if(scc[ma[i].from]!=scc[ma[i].to])        ru[scc[ma[i].to]]++;    }    for(int i=1;i<=cnt;i++) if(!ru[i]) ans++;    cout<<ans;    return;}int main(){    solve();    return 0;}