树不要皮,必死无疑;人不要脸,天下无敌|

Tx_Lcy

园龄:2年8个月粉丝:6关注:6

CF1213F Unstable String Sort

题目传送门

思路

我们可以根据 piqi 建有向边,边 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;
}

本文作者:Tx_Lcy

本文链接:https://www.cnblogs.com/tx-lcy/p/16872666.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Tx_Lcy  阅读(42)  评论(1编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起