Gym 102501 F Icebergs —— 贪心

This way

题意:

有s种动物,T种交换可能,就是说两个动物如果相邻并且他们有交换可能,你就可以交换这两种动物,最后是N只动物,让你在不违反交换可能的前提下使得他们最终排列的字典序最小。

题解:

这道题不错啊,我没有想对,也没时间敲了。
对于没有交换可能的两只动物来说,它们的先后顺序一定不会变。那么Q[i]队列就表示第i种动物有多少中断,也就是有多少不可交换的位置。那么我们枚举答案的位置,那么ans优先队列表示在这个位置的所有交换可能中,字典序最小的数是什么。之后枚举ans.top离开了以后,后面有哪些数可以交换到下一个位置了,No数组就表示每种数可以到第几个了。

#include
using namespace std;
string s[205];
unordered_mapId;
int a[100005];
int mp[205][205],No[205],pos[205];
queueQ[205];
priority_queue, greater >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<

你可能感兴趣的:(想法,贪心)