题目:
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;
}