萌新求助强连通
  • 板块学术版
  • 楼主kbzcz
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/8/26 11:37
  • 上次更新2023/10/27 13:37:44
查看原帖
萌新求助强连通
416192
kbzcz楼主2022/8/26 11:37

洛谷上似乎没有这题,题目大概是给出一个有向图有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;
}
2022/8/26 11:37
加载中...