洛谷上似乎没有这题,题目大概是给出一个有向图有n个点和m条有向边,输出连通分量的数量。我没看懂为什么要
low[x]=min(low[x], dfn[y]);
而不是
low[x]=min(low[x], low[y]);
哪位大佬可以解答一下?
代码:
#include<bits/stdc++.h>
using namespace std;
struct edge{int x,y,pre;}a[2110000];int alen,last[21000];
void ins(int x,int y){++alen;a[alen]=edge{x,y,last[x]}; last[x]=alen;}
int id,low[21000],dfn[21000];
int tp,sta[21000];bool v[21000];
int cnt,belong[21000];
void dfs(int x)
{
dfn[x]=low[x]=++id;
sta[++tp]=x;v[x]=1;
for(int k=last[x];k>0;k=a[k].pre)
{
int y=a[k].y;
if(dfn[y]==0)
{
dfs(y);
low[x]=min(low[x], low[y]);
}
else if(v[y]==1)
{
low[x]=min(low[x], dfn[y]);//这里
}
}
if(low[x]==dfn[x])
{
cnt++;int xx;
do
{
xx=sta[tp--];v[xx]=0;
belong[xx]=cnt;
}while(xx!=x);
}
}
int main()
{
int n,m;scanf("%d%d",&n,&m);
alen=0;memset(last,0,sizeof(last));
for(int i=1;i<=m;i++)
{
int x,y; scanf("%d%d",&x,&y);
ins(x,y);
}
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(v,0,sizeof(v));
memset(belong,0,sizeof(belong));
id=tp=cnt=0;
for(int i=1;i<=n;i++)if(dfn[i]==0)dfs(i);
printf("%d\n",cnt);
return 0;
}