建图思维拓扑排序建图+序列自动机——swerc Gym - 102501G 好题

Posted zsben991126

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了建图思维拓扑排序建图+序列自动机——swerc Gym - 102501G 好题相关的知识,希望对你有一定的参考价值。

思考了挺久的一题,主要卡在建图这一块,序列上的问题很难想到图论上。。

可以交换位置是一种关系,那么不能交换也是一种关系:两个不是朋友的点,相对位置保持不变!

不能交换的关系的两点就可以连边,在图上u->v就表示u一定在v前面

但是这样暴力建图显然会炸,我们再进行优化:

我们把动物i(设物种x)和其后面第一个物种也是x的点连边,那么每个点只要考虑其后面每种物种的第一个动物即可,那么每个点最多连200条边(想想为什么)

用序列自动机预处理一下+建图就好了

 

  

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define mk make_pair
vector<string>v;
int s,l,n,a[N],g[205][206];
map<string,int>mp;
map<int,string>mpp;

int nxt[N][205],pos[205],in[N];
vector<int>G[N];

void build(){
    for(int i=1;i<=s;i++)pos[i]=n+1;
    for(int i=n;i>=1;i--){
        for(int j=1;j<=s;j++)
            nxt[i][j]=pos[j];
        pos[a[i]]=i;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=s;j++)
            if(nxt[i][j]!=n+1 && !g[a[i]][j]){
                G[i].push_back(nxt[i][j]);
                in[nxt[i][j]]++;
            }
    }
}
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>> >q; 
int ans[N],tp,vis[N];
void topsort(){
    for(int i=1;i<=n;i++)if(in[i]==0)q.push(mk(a[i],i));
    while(q.size()){
        int u=q.top().second;
        ans[++tp]=q.top().first;
        q.pop();
        for(auto vv:G[u]){
            in[vv]--;
            if(in[vv]==0)q.push(mk(a[vv],vv));
        }
    }
}

int cmp(string a,string b){
    int res=a.compare(b);
    return res<0;
}

int main(){
    //freopen("test07.in","r",stdin);
    cin>>s>>l>>n;
    for(int i=1;i<=s;i++){
        string s;cin>>s;
        v.push_back(s);
    }    
    sort(v.begin(),v.end(),cmp);
    for(int i=0;i<v.size();i++){
        mp[v[i]]=i+1,mpp[i+1]=v[i];
        //cout<<v[i]<<" "<<mp[v[i]]<<‘
‘;
    }
    for(int i=1;i<=l;i++){
        string a,b;cin>>a>>b;
        int u=mp[a],v=mp[b];
        //cout<<u<<" "<<v<<‘
‘;
        g[u][v]=g[v][u]=1;
    }
    for(int i=1;i<=n;i++){
        string s;cin>>s;
        a[i]=mp[s];
        //cout<<s<<" "<<mp[s]<<"
";
    }
    build();
    topsort();
    for(int i=1;i<=n;i++)cout<<mpp[ans[i]]<<" ";
}

 

以上是关于建图思维拓扑排序建图+序列自动机——swerc Gym - 102501G 好题的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces825 E. Minimal Labels(思维,反向建图+拓扑排序)

[拓扑排序 反向建图] 825E - Minimal Labels

hdu4857 逃生反向建图+拓扑排序

hdu 4857/BestCoder Round#1 1001(拓扑排序+逆向建图)

bzoj5017 [Snoi2017]炸弹 (线段树优化建图+)tarjan 缩点+拓扑排序

hdu 4857 逃生 拓扑排序+逆向建图