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

来源:互联网 发布:java分布式锁原理 编辑:程序博客网 时间:2024/06/07 07:30

/*题意自己看。思路是先找出每个字符对应矩形框的的边界,即四个角的值。然后排个序。对每个字符对应的矩型框,扫描在矩形框上和该字符不相同的字符,然后在这两个字符之间连一条边,更新后一个字符的入度,有个需要注意的地方就是对每一个字符的矩形框上的不同字符,若出现好几次,则只更新一次入度,这个可以用一个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;}