Frame Stacking 良好的拓扑排序题 hoj&poj

Frame Stacking 很好的拓扑排序题 hoj&poj

/*题意自己看。
思路是先找出每个字符对应矩形框的的边界,即四个角的值。
然后排个序。
对每个字符对应的矩型框,扫描在矩形框上和该字符不相同的字符,然后在这两个字符之间连一条边,
更新后一个字符的入度,有个需要注意的地方就是对每一个字符的矩形框上的不同字符,
若出现好几次,则只更新一次入度,这个可以用一个bool数组来判重。
然后图统计好之后就开始拓扑排序。
因为要按字典序输出多组解。
所有采用DFS进行拓扑。
这个题编码有难度,思路也不错,是一道值得推荐的拓扑排序。*/
#include <stdio.h>
#include <cstring>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
struct MAP
{
    int r,l,u,d;
} MAP[26];
char m[31][31];
char letter[26];
bool top[31][31];
int in[31];
map <char,int> mp;
char route[31];
int n,mm,t,num;
void topsort()
{
    if(t==num)
    {
        printf("%s\n",route);
        return ;
    }
    for(int i=1; i<=num; i++)
    {
        if(in[i]==0)
        {
            in[i]--;
            route[t++]=letter[i];
            for(int j=1; j<=num; j++)
            {
                if(top[i][j])
                    in[j]--;
            }
            topsort();
            t--;
            in[i]++;
            for(int j=1; j<=num; j++)
            {
                if(top[i][j])
                    in[j]++;
            }
        }
    }
}
int main()
{
    char s[31];
    while(scanf("%d%d",&n,&mm)==2)
    {
        memset(m,0,sizeof(m));
        memset(in,0,sizeof(in));
        memset(top,false,sizeof(top));
        num=1;
        mp.clear();
        for(int i=0; i<n; i++)
        {
            scanf("%s",s);
            for(int j=0; j<strlen(s); j++)
            {
                m[i][j]=s[j];
                if(mp[s[j]]==0&&s[j]>='A'&&s[j]<='Z')
                {
                    letter[num]=s[j];
                    mp[s[j]]=num;
                    num++;
                }
            }
        }
        sort(letter+1,letter+num);
        num--;
        mp.clear();
        for(int i=1; i<=num; i++)
            mp[letter[i]]=i;
        for(int k=1; k<=num; k++)
        {
            char tmp=letter[k];
            MAP[k].l=MAP[k].u=10000;
            MAP[k].r=MAP[k].d=-1;
            for(int i=0; i<n; i++)
                for(int j=0; j<mm; j++)
                {
                    if(m[i][j]==tmp&&j<MAP[k].l) MAP[k].l=j;
                    if(m[i][j]==tmp&&j>MAP[k].r) MAP[k].r=j;
                    if(m[i][j]==tmp&&i>MAP[k].d) MAP[k].d=i;
                    if(m[i][j]==tmp&&i<MAP[k].u) MAP[k].u=i;
                }
        }
        for(int k=1; k<=num; k++)
        {
            for(int i=MAP[k].u; i<=MAP[k].d; i++)
            {
                int l=MAP[k].l;
                char u=m[i][l];
                if(u!=letter[k]&&!top[k][mp[u]])
                {
                    top[k][mp[u]]=true;
                    in[mp[u]]++;
                }
            }
            for(int i=MAP[k].u; i<=MAP[k].d; i++)
            {
                int r=MAP[k].r;
                char u=m[i][r];
                if(u!=letter[k]&&!top[k][mp[u]])
                {
                    top[k][mp[u]]=true;
                    in[mp[u]]++;
                }
            }
            for(int i=MAP[k].l+1; i<MAP[k].r; i++)
            {
                int r=MAP[k].u;
                char u=m[r][i];
                if(u!=letter[k]&&!top[k][mp[u]])
                {
                    top[k][mp[u]]=true;
                    in[mp[u]]++;
                }
            }
            for(int i=MAP[k].l+1; i<MAP[k].r; i++)
            {
                int r=MAP[k].d;
                char u=m[r][i];
                if(u!=letter[k]&&!top[k][mp[u]])
                {
                    top[k][mp[u]]=true;
                    in[mp[u]]++;
                }
            }
        }
        t=0;
        memset(route,0,sizeof(route));
        topsort();
    }
    return 0;
}