码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2020-06-14 00:58:46      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:cout   思考   fir   queue   span   build   turn   第一个   mpp   

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

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

不能交换的关系的两点就可以连边,在图上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]]<<‘\n‘;
    }
    for(int i=1;i<=l;i++){
        string a,b;cin>>a>>b;
        int u=mp[a],v=mp[b];
        //cout<<u<<" "<<v<<‘\n‘;
        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]<<"\n";
    }
    build();
    topsort();
    for(int i=1;i<=n;i++)cout<<mpp[ans[i]]<<" ";
}

 

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

标签:cout   思考   fir   queue   span   build   turn   第一个   mpp   

原文地址:https://www.cnblogs.com/zsben991126/p/13122345.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!