煩人的依賴(拓撲排序)

煩人的依賴(拓撲排序)

傳送門

思路:拓撲排序,因爲要滿足最小字典序,所以可以用優先隊列進行實現。先將每個字符串轉換爲一個結點,這裏用哈希表即可,然後將每個結點的邊也進行排序,最後用拓撲排序的板子即可。

AC代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e4+10;
#define mst(a) memset(a,0,sizeof a)
string s[N];
int ans[N];
vector<int>e[N];
int in[N],kase;
int n,m;
unordered_map<string,int>mp;
void toposort(){
    priority_queue<int>q;
    int vis[N]={};
    for(int i=1;i<=n;i++)
       if(!in[i]) q.push(-i),vis[i]=1;//用負號大根堆轉小根堆. 
    int k=0;
    while(q.size()){
        int now=q.top();q.pop();
        now=-now;
        ans[++k]=now;
        for(auto v:e[now]){
            in[v]--;
            if(!in[v]) q.push(-v),vis[v]=1;
        }
    }
    printf("Case #%d:\n",++kase);
    for(int i=1;i<=n;i++) if(!vis[i]){
         puts("Impossible");
        return ;
    }
    for(int i=1;i<=n;i++){
         cout<<s[ans[i]]<<'\n';
    }
}
int main(){
    int  t;
    scanf("%d",&t);
    while(t--){
        mp.clear();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            cin>>s[i],in[i]=0,e[i].clear();
        sort(s+1,s+n+1);//字典序. 
        for(int i=1;i<=n;i++) mp[s[i]]=i;
        for(int i=1;i<=m;i++){
            string a,b;
            cin>>a>>b;
            e[mp[a]].push_back(mp[b]);
            in[mp[b]]++;
        }
        for(int i=1;i<=n;i++) sort(e[i].begin(),e[i].end());//滿足字典序 
        toposort();
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章