zoukankan      html  css  js  c++  java
  • 【建图】【思维】拓扑排序建图+序列自动机——swerc Gym

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

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

    不能交换的关系的两点就可以连边,在图上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]]<<" ";
    }
  • 相关阅读:
    puppet之模板和类
    puppet之资源
    puppet自动化安装服务
    puppet自动化搭建lnmp架构
    puppet工简介一
    CDN杂谈
    cdn工作原理
    mysql之innodb存储引擎
    Android应用开发基础篇(11)-----ViewFlipper
    Android应用开发基础篇(10)-----Menu(菜单)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/13122345.html
Copyright © 2011-2022 走看看