题意:
有s种动物,T种交换可能,就是说两个动物如果相邻并且他们有交换可能,你就可以交换这两种动物,最后是N只动物,让你在不违反交换可能的前提下使得他们最终排列的字典序最小。
题解:
这道题不错啊,我没有想对,也没时间敲了。
对于没有交换可能的两只动物来说,它们的先后顺序一定不会变。那么Q[i]队列就表示第i种动物有多少中断,也就是有多少不可交换的位置。那么我们枚举答案的位置,那么ans优先队列表示在这个位置的所有交换可能中,字典序最小的数是什么。之后枚举ans.top离开了以后,后面有哪些数可以交换到下一个位置了,No数组就表示每种数可以到第几个了。
#include<bits/stdc++.h>
using namespace std;
string s[205];
unordered_map<string,int>Id;
int a[100005];
int mp[205][205],No[205],pos[205];
queue<int>Q[205];
priority_queue<int,vector<int>, greater<int> >ans;
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
int S,L,N;
cin>>S>>L>>N;
for(int i=1;i<=S;i++)
cin>>s[i];
sort(s+1,s+1+S);
int cnt=0;
for(int i=1;i<=S;i++)
Id[s[i]]=++cnt;
string s1,s2;
for(int i=1;i<=L;i++){
cin>>s1>>s2;
int v1=Id[s1],v2=Id[s2];
mp[v1][v2]=mp[v2][v1]=1;
}
for(int i=1;i<=S;i++)
mp[i][i]=0;
for(int i=1;i<=N;i++)
cin>>s1,a[i]=Id[s1];
for(int i=1;i<=S;i++){
int num=0;
for(int j=1;j<=N;j++){
if(a[j]==i)
Q[a[j]].push(num);
if(mp[a[j]][i]==0)
num++;
}
}
for(int i=1;i<=N;i++){
for(int j=1;j<=S;j++){
while(!Q[j].empty()&&No[j]>=Q[j].front()){
ans.push(j);
Q[j].pop();
}
}
cout<<s[ans.top()]<<" ";
for(int j=1;j<=S;j++)
if(mp[ans.top()][j]==0)
No[j]++;
ans.pop();
}
cout<<endl;
return 0;
}