简单地说,就是给出一张名字的列表,要找到一张字母表使得这张人名的列表是按字典序排列的。
这不就是今年天梯赛的原题嘛?
拓扑排序没的说
需要注意的点:可能存在前缀相等但是长度不等 判断possible或者impossible的时候这种情况非常容易忽略
再就是如果拓扑排序存在环 也就是最后仍然存在度数不为0的点
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=105;
int n,cnt,tot;
map<char,int>mp;
map<int,char>rk;
vector<int>Q[maxn];
queue<int>QQ;
int du[maxn];
bool flag;
char ans[maxn];
string s[maxn];
void add(int u,int v){
Q[u].push_back(v);
du[v]++;
}
void calc(string,string);
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>s[i];
for(int i=2;i<=n;i++)
calc(s[i-1],s[i]);
for(int i=1;i<=cnt;i++)
if(!du[i])QQ.push(i);
while(!QQ.empty()){
int u=QQ.front();
QQ.pop();ans[++tot]=rk[u];
for(int i=0;i<Q[u].size();i++){
int to=Q[u][i];
du[to]--;
if(!du[to])QQ.push(to);
}
}
if(tot!=cnt||flag)cout<<"Impossible";
else {
for(char i='a';i<='z';i++)
if(!mp.count(i))
ans[++tot]=i;
for(int i=1;i<=tot;i++)cout<<ans[i];
}
return 0;
}
void calc(string a,string b){
int len=min(a.size(),b.size());
bool cmp=1;
for(int i=0;i<len;i++){
if(a[i]!=b[i]){
if(!mp.count(a[i]))mp[a[i]]=++cnt,rk[cnt]=a[i];
if(!mp.count(b[i]))mp[b[i]]=++cnt,rk[cnt]=b[i];
add(mp[a[i]],mp[b[i]]);
cmp=0;
break;
}
}
if(cmp==1&&a.size()>b.size())flag=1;
}