煩人的依賴(拓撲排序)
思路:拓撲排序,因爲要滿足最小字典序,所以可以用優先隊列進行實現。先將每個字符串轉換爲一個結點,這裏用哈希表即可,然後將每個結點的邊也進行排序,最後用拓撲排序的板子即可。
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;
}