codeforces1213F tarjan reduced topological sorting point +

The meaning of problems

Given the arrangement of two lengths of n p and q, satisfying construct a string s \ (s [p_i] <= s [p_ {i + 1}] \) and \ (s [q_i] <= s [q_ I. 1} + {] \) , and the number of different character strings satisfies not less than k.

analysis

Build a directed graph, \ (P_i \) to \ (p_ {i + 1} \) is connected a directed edge, \ (Q_I \) to \ (q_ {i + 1} \) is connected a directed edge.

A point on the chain, we can let greedy characters each point increment, incremented to 'z', the remaining characters are all equal so that 'z', and the characters of all point in the same ring must be the same, can be all rings are shrunk to a point, this picture becomes a directed acyclic graph, topological sorting can be done directly.

Code

#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
#define pb push_back
#define ll long long
using namespace std;
const int inf=1e9;
const int mod=1e9+7;
const int maxn=2e5+10;
int n,k;
int low[maxn],dfn[maxn],st[maxn],inst[maxn],top=-1,cnt,scnt,sc[maxn];
vector<int>g[maxn];
set<int>f[maxn];
int d[maxn],rk[maxn];
int res=-1;
void dfs(int u){
    dfn[u]=low[u]=++cnt;
    st[++top]=u;
    inst[u]=1;
    for(int x:g[u]){
        if(!dfn[x]){
            dfs(x);
            low[u]=min(low[u],low[x]);
        }else if(inst[x]){
            low[u]=min(low[u],dfn[x]);
        }
    }
    if(low[u]==dfn[u]){
        scnt++;
        while(true){
            int x=st[top--];
            sc[x]=scnt;
            inst[x]=0;
            if(x==u) break;
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    //freopen("in","r",stdin);
    cin>>n>>k;
    int x,y;
    cin>>x;
    int rt=x;
    for(int i=1;i<n;i++){
        cin>>y;
        g[x].pb(y);
        x=y;
    }
    cin>>x;
    for(int i=1;i<n;i++){
        cin>>y;
        g[x].pb(y);
        x=y;
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]) dfs(i);
    }
    for(int i=1;i<=n;i++){
        for(int x:g[i]){
            if(sc[i]!=sc[x]) f[sc[i]].insert(sc[x]);
        }
    }
    for(int i=1;i<=n;i++)
        for(int x:f[i])
            d[x]++;
    queue<int>q;
    int mx=-1;
    for(int i=1;i<=scnt;i++) rk[i]=-1;
    for(int i=1;i<=scnt;i++){
        if(d[i]==0) q.push(i),rk[i]=mx=0;
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int x:f[u]){
            rk[x]=max(rk[u]+1,rk[x]);
            rk[x]=min(25,rk[x]);
            mx=max(mx,rk[x]);
            if(--d[x]==0) q.push(x);
        }
    }
    if(mx+1<k) cout<<"NO\n";
    else{
        cout<<"YES\n";
        for(int i=1;i<=n;i++){
            cout<<(char)(rk[sc[i]]+'a');
        }cout<<'\n';
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/xyq0220/p/11729187.html