acwing154/LGp1155 双栈排序

性质
若存在k>i>j且a[k]<a[i]<a[j] 则i,j不可被放进同一个栈
充分性、必要性均易证

对这样的i,j连一条无向边,再判断整个图是不是二分图

代码

#include<iostream>
#include<cstdio>
#include<memory.h>
using namespace std;
int n;
bool mark;
int a[1005];
struct edge
{
	int to,nxt;
}e[1000005];
int h[1005],tot;
int col[1005];
void add_edge(int x,int y)
{
	e[++tot].to=y;
	e[tot].nxt=h[x];
	h[x]=tot;
}
void dfs(int x)
{
	for(int i=h[x];i;i=e[i].nxt)
	{
		if(col[e[i].to]==-1)
		{
			col[e[i].to]=col[x]^1;
			dfs(e[i].to);
		}
		else if(col[e[i].to]==col[x]){mark=true;return;} 
	}
}
int s1[1005],s2[1005],top1,top2;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&a[i]);
	}
	int k=a[n];
	for(int i=n-1;i>=1;--i)
	{
		for(int j=i-1;j>=1;--j)
		{
			if(a[j]<a[i]&&k<a[j])
			{
				add_edge(i,j),add_edge(j,i);
			}
		}
		k=min(k,a[i]);
	}
	memset(col,-1,sizeof(col));
	for(int i=1;i<=n;++i)
	{
		if(col[i]==-1)
		{
			col[i]=0,dfs(i);
			if(mark)break;
		}
	}
	
	if(mark)
	{
		printf("0\n");
		return 0;
	}
	int num=1;
	for(int i=1;i<=n;++i)
	{
		if(col[i]==0)
		{
			s1[++top1]=a[i];
			printf("a ");
		}
		else
		{
			s2[++top2]=a[i];
			printf("c ");
		}
		while(num==s1[top1]||num==s2[top2])
		{
			if(num==s1[top1])printf("b "),--top1;
			else printf("d "),--top2;
			++num;
		}
	}
	printf("\n");
	return 0;
}
发布了25 篇原创文章 · 获赞 1 · 访问量 318

猜你喜欢

转载自blog.csdn.net/qq_43665203/article/details/104224883