本题需要一些构图上的小优化,构图之后博主我选择使用DFS来进行拓扑排序的操作,详情见代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdlib>
#include<string>
#include<cassert>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#define clean(n,m) memset(n,m,sizeof(n))
using namespace std;
#define maxn 32
#define maxm 28
char map[maxn][maxm], ans[maxm];
int m, n, in[maxn], total;
bool edge[maxn][maxm];
struct Node
{
int x, y;
}lt[maxm],rb[maxm];
void getMap()
{
clean(edge, false);
clean(in, -1);
clean(lt, 0x3f);
clean(rb, -1);
for (int i = total = 0;i < n;i++)
{
for (int j = 0;j < m;j++)
{
if (map[i][j] == '.')
continue;
int t = map[i][j] - 'A';
if (in[t] == -1)
{
in[t] = 0;
total++;
}
if (i < lt[t].x)
lt[t].x = i;
if (i > rb[t].x)
rb[t].x = i;
if (j < lt[t].y)
lt[t].y = j;
if (j > rb[t].y)
rb[t].y = j;
}
}
for (int i = 0;i < maxn;i++)
{
if (in[i] == -1)
continue;
for (int x = lt[i].x;x <= rb[i].x;x++)
{
for (int y = lt[i].y;y <= rb[i].y;y++)
{
if (x > lt[i].x&&y > lt[i].y&&x < rb[i].x&&y < rb[i].y)
continue;
int t = map[x][y] - 'A';
if (t != i&&!edge[i][t])
{
edge[i][t] = true;
in[t]++;
}
}
}
}
}
void dfs(int id)
{
if (id == total)
{
ans[id] = '\0';
cout << ans << endl;
return;
}
for (int i = 0;i < maxn;i++)
{
if (in[i] == 0)
{
ans[id] = 'A' + i;
in[i] = -1;
for (int j = 0;j < maxn;j++)
{
if (edge[i][j])
in[j]--;
}
dfs(id + 1);
in[i] = 0;
for (int j = 0;j < maxn;j++)
{
if (edge[i][j])
in[j]++;
}
}
}
}
int main()
{
while (cin >> n >> m)
{
for (int i = 0;i < n;i++)
cin >> map[i];
getMap();
dfs(0);
}
return 0;
}