因为维护的是偏序关系,很容易可以发现是拓扑排序裸题。
一个字母写错了调了半天。
可以用堆维护字典序。
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
#define Min(_A,_B) ((_A)<(_B)?(_A):(_B))
int in[30],n,len[1005],at=0,ss[30];
bool mp[30][30];
char ch[105][105];
char ans[30];
inline void CMP(const int &A,const int &B){
int le=Min(len[A],len[B]);
for(int i=1;i<=le;++i){
if(ch[A][i]!=ch[B][i]){
if(!mp[ch[A][i]-'a'][ch[B][i]-'a']){
mp[ch[A][i]-'a'][ch[B][i]-'a']=1;
++in[ch[B][i]-'a'];
}
return;
}
}
if(len[A]>len[B]){
puts("Impossible");
exit(0);
}
}
priority_queue< int,vector<int>,greater<int> > q;
inline void srt(){
for(int i=0;i<26;++i){
if(!in[i]){
q.push(i);
}
}
int p;
while(!q.empty()){
p=q.top();
q.pop();
ans[++at]=p+'a';
for(int i=0;i<26;++i){
if(mp[p][i]){
--in[i];
if(!in[i]){
q.push(i);
}
}
}
}
if(at<26){
puts("Impossible");
exit(0);
}
ans[++at]='\0';
}
void init(){
scanf("%d",&n);
memset(mp,0,sizeof(mp));
memset(in,0,sizeof(in));
for(int i=1;i<=n;++i){
cin>>ch[i]+1;
len[i]=strlen(ch[i]+1);
}
for(int i=1;i<n;++i){
CMP(i,i+1);
}
srt();
cout<<ans+1;
}
int main(){
init();
return 0;
}