2021牛客暑期多校训练营10 F题

题目链接

文章目录

思路

这道题很关键的在于将栈中的序列转为树结构,每一个入栈后的序列不同转为对于每一个父节点,他的孩子节点的颜色不能相同

AC代码

#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
#define pii pair<int,int> 
#define N 2000000+9
#define mem(a,b) memset(a,b,sizeof a)
#define ft first
#define sd second
priority_queue<pii> q;
int a[N*2],h[N*2],e[N*2],ne[N*2],idx,pos[N*2],ans[N*2];
void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
//dfs遍历我们建立的树,进行染色 
void dfs(int x)
{
	//puts("debug");
	//if(!ok) return ;
	//下面先对x结点的sz[x]个儿子进行染色
	vector<pii> v; 
	for(int i=h[x]; ~i; i=ne[i])
	{
		//j是i的儿子结点 
		int j=e[i];
		if(q.size()==0)
		{
			puts("NO");
			exit(0);
		}
		auto tmp=q.top();
		q.pop();
		tmp.ft--;
		ans[j]=tmp.sd;
		if(tmp.ft) v.push_back(tmp);
	}
	//如果用了的sz[z]中颜色还有剩下,那么就存入队列 
	for(int i=0; i<v.size(); i++)  q.push(v[i]);
	for(int i=h[x]; ~i; i=ne[i])
	{
		dfs(e[i]);
	}
	return ;
}
int  main()
{
	mem(h,-1);
	int n;
	cin>>n;
    string s;
    cin>>s;
    for(int i=1; i<=n; i++)
    {
    	int x;
    	scanf("%d",&x);
    	a[x]++;
	}
	for(int i=1; i<=n; i++) if(a[i]) q.push({a[i],i});
	//建树 
	int tt=0; 
	int num=0; 
	for(int i=0; i<s.size(); i++)
	{
		if(s[i]=='(')
		{
			++tt;
			pos[tt]=++num;
			add(pos[tt-1],num);
			//sz[pos[tt-1]]++;
		}
		else tt--;
	}
	//puts("debug");
	dfs(0);
	puts("YES");
	for(int i=1; i<=n; i++)  printf("%d ",ans[i]); 
	return 0;
 } 
posted @ 2022-08-28 08:43  翔村亲亲鸟  阅读(10)  评论(0编辑  收藏  举报