https://vijos.org/p/1023
此题虽然可以并查集AC,但是实际上并查集是错误的
这道题只能用tarjan算法求强连通分量,因为这个是一个有向图,而并查集只能求无向图的强连通分量
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
#include<cmath>
#define ms(i,j) memset(i, j, sizeof(i));
using namespace std;
struct node
{
int x;
int y;
};
vector<node> q[205];
stack<int> s;
int n;
int index = 0;
int ans = 0;
int ex[205];
int dn[205], low[205];
int tarjan(int u)
{
dn[u]=low[u]=++index;
ex[u]=-1;
s.push(u);
node p;
for (int i=0;i<q[u].size();i++)
{
p = q[u][i];
if (ex[p.y]==0) {
tarjan(p.y);
low[u] = min(low[u], low[p.y]);
} else if (ex[p.y]==-1)
{
low[u] = min(low[u], dn[p.y]);
}
}
if (dn[u]==low[u])
{
int e;
do
{
e = s.top();
s.pop();
ex[e] = 1;
} while (u!=e);
ans++;
}
}
int main ()
{
scanf("%d", &n);
for (int i=1;i<=n;i++)
{
int a;
scanf("%d", &a);
while (a!=0)
{
node r;
r.x = i, r.y = a;
q[i].push_back(r);
scanf("%d", &a);
}
}
ms(ex, 0);
ms(dn,0);
for (int i=1;i<=n;i++)
if (!dn[i]) tarjan(i);
printf("%d\n", ans);
return 0;
}