喵喵啦 ~>_<~
  • 板块灌水区
  • 楼主Atri_Lobato
  • 当前回复7
  • 已保存回复7
  • 发布时间2024/8/26 20:09
  • 上次更新2024/8/26 21:52:47
查看原帖
喵喵啦 ~>_<~
1065103
Atri_Lobato楼主2024/8/26 20:09

在看点双

大概看懂了,,,但是实现的时候有一些疑问

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int n,m;
vector<int> pic[500005];
int top=0;
int dfn[500005];
int low[500005];
int order=0;
int stck[500005];
vector<int> dc[500005];
int cnt=0;
void Tarjan(int now,int father)
{
	order++;
	dfn[now]=order;
	low[now]=order;
	top++;
	stck[top]=now;
	bool flag=0;
	for(int i=0;i<pic[now].size();i++)
	{
		int next=pic[now][i];
		if(dfn[next]==0)
		{
			flag=1;
			Tarjan(next,now);
			low[now]=min(low[now],low[next]);
			if(low[next]>=dfn[now])
			{
				cnt++;
				while(stck[top+1]!=next)
				{
					dc[cnt].push_back(stck[top]); 
					top--;
				}
				dc[cnt].push_back(now); 
			}
		}
		else if(next!=father)
		{
			low[now]=min(low[now],dfn[next]);
		}
	}
	if(father==0&&flag==0)
	{
		dc[++cnt].push_back(now); 
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		pic[x].push_back(y);
		pic[y].push_back(x);  
	}
	for(int i=1;i<=n;i++)
	{
		if(dfn[i]==0)
		{
			Tarjan(i,0);
		}
	}
	printf("%d\n",cnt);
	for(int i=1;i<=cnt;i++)
	{
		printf("%d ",dc[i].size());
		for(int q=0;q<dc[i].size();q++)
		{
			printf("%d ",dc[i][q]);
		}
		printf("\n");
	}
	return 0;
}

这是满分代码,其中


if(low[next]>=dfn[now])
{
	cnt++;
	while(stck[top+1]!=next)
	{
		dc[cnt].push_back(stck[top]); 
		top--;
	}
	dc[cnt].push_back(now); 
}

改为


if(low[next]>=dfn[now])
{
	cnt++;
	while(stck[top]!=now)
	{
		dc[cnt].push_back(stck[top]); 
		top--;
	}
	dc[cnt].push_back(now); 
}

就错了一部分qaq

有点没弄懂,处理边双的时候不是一定会把整棵子树都处理完才开新子树的处理嘛。。。那样子退栈到now和退完next不是等价的喵 为什么会错呢qaq

2024/8/26 20:09
加载中...