[ 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<