Train Wreck
题目链接:https://ac.nowcoder.com/acm/contest/108199/F
题意:
给定一个括号栈序列,以及一些颜料,要求每次入栈后,栈中的颜料序列不能重复出现
输出符合条件的颜料序列。
思路:
可以将括号栈操作看作建树过程
初始树的根节点为0
1.入栈操作
在当前节点下延申出一个子节点,并将子节点设置为当前节点
2.出栈操作
将当前节点回溯至其父节点上
那么约束条件即为:树上任意一个非叶子节点的直接儿子节点都两两不同
那么对于一个节点,对其直接儿子节点的染色过程就有说法了
由于颜料个数有限,为了尽量使直接儿子节点们两两不同,我们需要先取出颜料个数最多的那些颜料进行染色
因为如果颜料个数少的颜料染色,到后面颜料的选择就会变少,使约束条件不成立(即到达某个直接儿子节点时没有可供选择的颜料了)的概率增加
为了维护颜料个数多的颜料,需要使用优先队列。
void dfs(int u){
if(!f)return;
vector<pii>p;
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(v==fa[u])continue;
if(q.size()){
pii color=q.top();
q.pop();
ans[v]=color.se;
if(color.fi>1){
p.pb((pii){color.fi-1,color.se});
}
}else{
f=0;return;
}
}
for(int i=0;i<p.size();i++){
q.push(p[i]);
}
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(v==fa[u])continue;
dfs(v);
if(!f)return;
}
}
void solve(){
int n;cin>>n;
int now=0;
int cnt=1;
rep(i,1,2*n){
char ch;cin>>ch;
if(ch=='('){
int temp=now;
now=cnt++;
fa[now]=temp;
e[now].pb(fa[now]);
e[fa[now]].pb(now);
}else{
now=fa[now];
}
}
map<int,int>mp;
rep(i,1,n){
int x;cin>>x;mp[x]++;
}
for(auto[x,y]:mp){
q.push({y,x});
}
dfs(0);
if(!f){
cout<<"NO"<<endl;
return;
}
cout<<"YES"<<endl;
rep(i,1,n){
cout<<ans[i]<<' ';
}
}

浙公网安备 33010602011771号