社区讨论

0分求调

P8436【模板】边双连通分量参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo16t83h
此快照首次捕获于
2023/10/22 16:08
2 年前
此快照最后确认于
2023/11/02 15:45
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e6+10;
int num,ans;
int n,m;
struct linkstar{
	int from,to,w,next;
}edge[2*MAXN];
int head[MAXN],dfn[MAXN],low[MAXN],vis[MAXN];
vector<int> dcc[MAXN];
bool bridge[2*MAXN];
int escnt,tim,root;
vector<int> vec;
void add(int u,int v)
{
	edge[++escnt].from=u;
	edge[escnt].to=v;
	edge[escnt].next=head[u];
	head[u]=escnt;
}
void tarjan(int u,int fa)
{
	dfn[u]=low[u]=++tim;
	for (int i=head[u];i!=-1;i=edge[i].next){
		int v=edge[i].to;
		if(dfn[v]==0){
			tarjan(v,i);
			low[u]=min(low[u],low[v]);
			if(low[v]>dfn[u]) bridge[i]=bridge[i^1]=1; 
		}
		else if(i!=(fa^1)){
			low[u]=min(low[u],dfn[v]);
		}
	}
}
void dfs(int u)
{
	vis[u]=num;
	if(u) dcc[num].push_back(u);
	for (int i=head[u];i!=-1;i=edge[i].next){
		int v=edge[i].to;
		if(bridge[i]) continue;
		if(!vis[v]) dfs(v);
	}
}
int main()
{
	memset(head,-1,sizeof(head));
	cin>>n>>m;
	int x,y;
	for (int i=1;i<=m;i++){
		cin>>x>>y;
		if(x==y) continue;
		add(x,y);
		add(y,x);
	}
	for (int i=1;i<=n;i++){
		if(!dfn[i])	tarjan(i,0);
	}
	for (int i=1;i<=n;i++){
		if(!vis[i]){
			num++;
			dfs(i);
		}
	}
	cout<<num<<endl;
	for (int i=1;i<=num;i++){
		cout<<dcc[i].size()<<" ";
		for (int j:dcc[i]) cout<<j<<" ";
		cout<<endl;
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...