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;}