简单的字符串拓扑应用。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 110;
vector<int> vec[maxn];
int n;
char s[maxn][maxn];
bool flag;
char ans[30];
bool link[maxn][maxn];
int indegree[maxn];
int cnt;
void Topsort()
{
int tmp = 0;
queue<int> q;
for(int i = 0; i < 26; i++)
{
if(!indegree[i])
q.push(i);
}
while(!q.empty())
{
int u = q.front();
q.pop();
ans[tmp++] = u + 'a';
int sz = vec[u].size();
for(int i = 0; i < sz; i++)
{
int t = vec[u][i];
indegree[t]--;
if(indegree[t] == 0)
q.push(t);
}
}
if(tmp == 26)
{
ans[tmp] = '\0';
cout << ans << endl;
}
else
cout << "Impossible" << endl;
}
int main()
{
cin >> n;
memset(link, 0, sizeof(link));
memset(indegree, 0, sizeof(indegree));
for(int i = 0; i < n; i++)
cin >> s[i];
flag = true;
for(int i = 0; i < n; i++)
{
for(int j = i + 1; j < n; j++)
{
int len1 = strlen(s[i]);
int len2 = strlen(s[j]);
int len = min(len1, len2);
bool dif = false;
for(int k = 0; k < len; k++)
{
if(s[i][k] != s[j][k])
{
dif = true;
int a = s[i][k] - 'a', b = s[j][k] - 'a';
//vec[a].push_back(b); 没有优化的情况
//indegree[b]++;
if(!link[a][b]) //优化,减少重复
{
vec[a].push_back(b);
link[a][b] = 1;
indegree[b]++;
}
break;
}
}
if(!dif && len1 > len2) //前长后短的情况必然错误
{
flag = false; break;
}
}
if(!flag) break;
}
if(!flag) cout << "Impossible" << endl;
else
{
Topsort();
}
return 0;
}