Swapping Places(字典序最小拓扑排序)

https://vjudge.net/problem/Gym-102501G

题意:

给你一个列表,L个可以交换的对(相邻的才能交换),问最后list表的字典序最小

解析:

发现不能交换的两种物品,其组成的相对位置不会改变。相同种类物品之间也不会改变。所以将这些相对位置建成边。跑一个字典序最小的拓扑排序就行。(优先队列)

代码:

#include
using namespace std;
typedef long long ll;
typedef long long LL;
typedef double db;
typedef ll TP;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define Fi first
#define Se second
#define _Out(a)	cerr<<#a<<" = "<<(a)<
const int MOD = 1e9+7, INF = 0x3f3f3f3f, MAXN = 1e5+ 50;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const db Pi = acos(-1), EPS = 1e-6;
void test() { cerr << "\n"; }template<typename T, typename...Args>void test(T x, Args...args) { cerr << x << " "; test(args...); }
inline ll qpow(ll a, ll b) {return b?((b&1)?a*qpow(a*a%MOD,b>>1)%MOD : qpow(a*a%MOD,b>>1))%MOD :1; }
inline ll qpow(ll a, ll b, ll c) {return b?((b&1)?a*qpow(a*a%c,b>>1)%c : qpow(a*a%c,b>>1)) % c: 1; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
int sign(db x) { return x<-EPS ? -1 : x>EPS; }
int dbcmp(db l, db r) { return sign(l - r); }
map<string,int>mp;
char rk[222][33];
bool G[222][222];
int laspos[222];
vector<int>to[MAXN];
int idx[MAXN];
int indu[MAXN];
string name[222];
struct SS
{
    int id,val;
    bool operator<(const SS&R)const
    {
        return val>R.val;
    }
};
void work() {
    int S,L,n;
    cin>>S>>L>>n;
    //scanf("%d%d%d",&S,&L,&n);
    for(int i=1;i<=S;i++)
    {
           //scanf("%s",tmps);
           string str;cin>>str;
           mp[str]=1;laspos[i]=-1;
    }
    int cntm=0;
    for(auto &x:mp)
    {
        x.second=++cntm;
        name[cntm]=x.first;
    }
    for(int i=1;i<=L;i++)
    {
        string str;
        cin>>str;
        int u=mp[str];assert(u);
        //scanf("%s",tmps);
        cin>>str;
        int v=mp[str];assert(v);
        G[u][v]=G[v][u]=1;
    }
    for(int i=1;i<=n;i++)
    {
        string str;cin>>str;
        int now=mp[str];idx[i]=now;
        assert(now);
        for(int j=1;j<=S;j++)
        {
            if(G[j][now])continue;
            if(laspos[j]==-1)continue;
            to[laspos[j]].push_back(i);
            indu[i]++;
        }
        laspos[now]=i;
    }
    priority_queue<SS>pq;
    for(int i=1;i<=n;i++)
    {
        if(indu[i]==0)pq.push({i,idx[i]});
    }
    int cntb=0;
    while(!pq.empty())
    {
        cntb++;
        SS tmp=pq.top();pq.pop();
        cout<<name[tmp.val]<<' ';
        for(int i=0;i<to[tmp.id].size();i++){
            int v=to[tmp.id][i];
            indu[v]--;
            if(indu[v]==0)pq.push({v,idx[v]});
        }
    }
    assert(n==cntb);
}
int main()
{
    std::ios::sync_with_stdio(false);
    work();
}

你可能感兴趣的:(图论/搜索)