烦人的依赖(拓扑排序)
思路:拓扑排序,因为要满足最小字典序,所以可以用优先队列进行实现。先将每个字符串转换为一个结点,这里用哈希表即可,然后将每个结点的边也进行排序,最后用拓扑排序的板子即可。
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;
}