CF1213F Unstable String Sort
思路
我们可以根据 \(p_i\) 和 \(q_i\) 建有向边,边 \(u,v\) 表示 \(u\) 需要小于等于 \(v\)。
然后跑一遍缩点。
不难发现在一个强连通分量里的点必须要相等,于是最多的不同字母个数即为 \(\min(26,tot)\),其中 \(tot\) 表示强连通分量的个数。
接下来我们已经把图缩成了一个 DAG,于是直接跑拓扑排序即可。
代码
#include<bits/stdc++.h>
using namespace std;
int const N=2e5+10;
char color[N];int rd[N],n,k,p[N],q[N];
vector<int>a[N],b[N];
int dfn[N],co[N],low[N],s[N],ind[N],top,cnt,tot;
inline void tarjan(int x){
dfn[x]=low[x]=++cnt;s[++top]=x;ind[x]=1;
for (auto v:a[x])
if (!dfn[v]) tarjan(v),low[x]=min(low[x],low[v]);
else if (ind[v]) low[x]=min(low[x],low[v]);
if (low[x]==dfn[x]){
++tot;
while (1){
int X=s[top--];
co[X]=tot;ind[X]=0;
if (!(x^X)) break;
}
}
}
inline void topo_sort(){
queue<int>q;
for (int i=1;i<=n;++i) if (!rd[i]) q.push(i),color[i]='a';
while (!q.empty()){
int x=q.front();q.pop();
for (auto v:b[x]){--rd[v];color[v]=max(color[v],min('z',char(color[x]+1)));if (!rd[v]) q.push(v);}
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>k;
for (int i=1;i<=n;++i) cin>>p[i];
for (int i=2;i<=n;++i) a[p[i-1]].push_back(p[i]);
for (int i=1;i<=n;++i) cin>>q[i];
for (int i=2;i<=n;++i) a[q[i-1]].push_back(q[i]);
for (int i=1;i<=n;++i) if (!dfn[i]) tarjan(i);
if (tot<k) return cout<<"NO\n",0;
for (int i=1;i<=n;++i)
for (auto v:a[i])
if (co[i]^co[v]) b[co[i]].push_back(co[v]),++rd[co[v]];
topo_sort();
cout<<"YES\n";
for (int i=1;i<=n;++i) cout<<color[co[i]];cout<<'\n';
return 0;
}

浙公网安备 33010602011771号