点/边双连通分量板子

点双

没写完

边双缩点

#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a);i<=(b);i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define db(x) cout<<"DEBUG "<<#x<<" = "<<x<<endl;
#define endl '\n'
using namespace std;

//#define SIZE (1<<20)
//char In[SIZE],Out[SIZE],*p1=In,*p2=In,*p3=Out;
//#define getchar() (p1==p2&&(p2=(p1=In)+fread(In,1,SIZE,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
	return x*f;
}
template<typename _T>
inline void write(_T x)
{
	static _T sta[35];int top=0;
	if(x<0) putchar('-'),x=-x;
	do{sta[top++]=x%10,x/=10;}while(x);
	while(top) putchar(sta[--top]+'0');
}

const int N=2e5+509,M=1e6+509,mod=998244353;

int n,m;

struct edge{int y,z,id;};
vector<edge> e[N];
vector<edge> bri;
int idx,dfn[N],low[N];
stack<int> sta;
int c[N],sccsum;
vector<int> scc[N];

void tarjan(int x,int fa)
{
	dfn[x]=low[x]=++idx;
	sta.push(x);
	for(auto &[y,z,id]:e[x])
	{
		if(id==fa) continue;
		if(!dfn[y])
		{
			tarjan(y,id);
			low[x]=min(low[x],low[y]);
		}
		else low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]==low[x])
	{
		int y;++sccsum;
		do
		{
			y=sta.top();sta.pop();
			scc[sccsum].push_back(y);
			c[y]=sccsum;
		}while(y!=x);
	}
}

vector<edge> g[N];
void build()
{
	fd(x,1,n)
	{
		for(auto &[y,z,id]:e[x])
			if(c[x]!=c[y])
				g[c[x]].push_back({c[y],z,id}),
				bri.push_back({x,y,id});
	}
}

signed main()
{
//#define FJ
#ifdef FJ
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
#else
//	freopen("A.in","r",stdin);
//	freopen("A.out","w",stdout);
#endif
//#define io
#ifdef io
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
#endif
	
	n=read(),m=read();
	fd(i,1,m)
	{
		int x=read(),y=read();
		e[x].push_back({y,1,i});
		e[y].push_back({x,1,i});
	}
	
	fd(i,1,n) if(!dfn[i]) tarjan(i,0);
	build();
	
	return 0;
}
posted @ 2024-11-28 09:33  whrwlx  阅读(2)  评论(0编辑  收藏  举报