[ cf Gym - 102501G ] 思维+拓扑排序


G. Swapping Places

特点:不能交换的元素之间的相对位置是不变的,这也意味着相同的元素之间相对位置不变。那么,我们可以对相对位置不变的元素由前点向当前点建边,按字典序进行拓扑排序。注意,字典序可以通过map容器获得(别手滑用了unordered_map!!),map默认是小根的,正好符合字典序升序。

#include
#define ll long long
#define pll pair
#define pii pair
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define mem0(x) memset(x,0,sizeof(x))
#define meminf(x) memset(x,0x3f,sizeof(x))
#define VI vector
#define VL vector
using namespace  std;

const int N = 1e5+5;
string str[205];
vector to[N];
map mp;
int last[205],idx[N];
int ok[205][205],in[N];
struct node{
    int id,val;
    bool operator<(node v)const {
        return val>v.val;
    }
};
int main(){
    ios::sync_with_stdio(0);
    int s,l,n;cin>>s>>l>>n;
    rep(i,1,s){
        string ts;
        cin>>ts;
        mp[ts] = 1;
        last[i] = -1;
    }
    int tcnt = 0;
    for(auto &v:mp){
        v.second = ++tcnt;
        str[tcnt] = v.first;
    }
    rep(i,1,l){
        string s1,s2;cin>>s1>>s2;
        int u = mp[s1],v = mp[s2];
        ok[u][v] = ok[v][u] = 1;
    }

    rep(i,1,n){
        string ts;cin>>ts;
        idx[i] = mp[ts];
        rep(j,1,s){
            if(ok[idx[i]][j]) continue;
            if(last[j]==-1) continue;
            to[last[j]].push_back(i);
            in[i]++;
        }
        last[idx[i]] = i;
    }
    priority_queue q;
    rep(i,1,n){
        if(!in[i]){
            q.push((node){i,idx[i]});
        }
    }

    while(!q.empty()){
        node tmp = q.top();q.pop();
        cout<

相关