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

G. Swapping Places

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

#include<bits/stdc++.h>
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#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<int>
#define VL vector<ll>
using namespace  std;

const int N = 1e5+5;
string str[205];
vector<int> to[N];
map<string,int> 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<node> q;
    rep(i,1,n){
        if(!in[i]){
            q.push((node){i,idx[i]});
        }
    }

    while(!q.empty()){
        node tmp = q.top();q.pop();
        cout<<str[tmp.val]<<' ';
        for(auto v:to[tmp.id]){
            in[v]--;
            if(!in[v]) q.push({v,idx[v]});
        }

    }
}
posted @ 2020-08-11 23:31  Cha2a_zzZ  阅读(179)  评论(0)    收藏  举报