CodeForces 510C Fox And Names (拓扑排序)

时间:2022-09-23 18:12:36

<题目链接>

题目大意:

给你一些只由小写字母组成的字符串,现在按一定顺序给出这些字符串,问你怎样从重排字典序,使得这些字符串按字典序排序后的顺序如题目所给的顺序相同。

解题分析:
本题想到拓扑排序就好做了。就是枚举每个字符串,每个字符串和它前一个字符串寻找第一个不同的字符,然后前一个串的该字符向当前串的字符连一条有向边(注意判断后一个串是前一个串的子串的情况)。然后就是跑一遍拓扑排序,如果不冲突的话,就可构造出答案。

#include <bits/stdc++.h>
using namespace std; #define pb push_back
string str[];
vector<int>G[];
int ind[];
vector<int>ans; inline void TopoSort(){
queue<int>q;
for(int i=;i<;i++){
if(!ind[i])q.push(i);
}
while(q.size()){
int u=q.front();q.pop();
ans.pb(u);
ind[u]=-;
for(int i=;i<G[u].size();i++){
int v=G[u][i]; //得到它的子节点
ind[v]--;
if(ind[v]==)q.push(v);
}
}
}
int main(){
int n;cin>>n;
for(int i=;i<=n;i++)
cin>>str[i];
for(int i=;i<=n;i++){ //枚举字符串
int len1=str[i-].size();
int len2=str[i].size();
bool fp=false;
for(int j=;j<min(len1,len2);j++){
if(str[i-][j]!=str[i][j]){
int u=str[i-][j]-'a';
int v=str[i][j]-'a';
G[u].pb(v);
ind[v]++; //记录这个点的入度
fp=true;
break;
}//找到第一个不同的元素
}
if(!fp&&len1>len2)return puts("Impossible"),; //如果当前串是前一个串的子串
}
TopoSort();
if(ans.size()<)puts("Impossible");
else {
for(int i=;i<ans.size();i++)
printf("%c",ans[i]+'a');
puts("");
}
}