poj 1128 Frame Stacking(DFS+拓扑排序)
2017-07-21 11:49
288 查看
Frame Stacking
题目链接:哈哈,在这里题意:每个图片由同一字母组成的边框表示,每个图片的字母都不同;
在一个最多30*30的区域放置这些边框,这些边框叠在一起,给出从上向下看的图。每个相框保证四条边上至少有一点出现。
求底层向顶层叠放的边框次序,多种结果按字典序输出
思路:先根据原始图,对每个字母的图片建立大致轮廓(记录左上和右下)
然后根据每个图片的轮廓建一个有向无环图,被覆盖的图片向覆盖它的图片建边
最后进行dfs形式的拓扑排序,从小到大遍历(字典序)。
代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; struct Node { int v,next; } E[10000]; struct Coordinate { int x,y; } L[30][2];//记录每个字母的左上角和右下角 int first[30],vis[30],in[30],inq[30][30]; char mp[30][30],ans[30]; int len,Totalnum,n,m; void add_edge(int u,int v)//邻接表存边 { E[len].v=v,E[len].next=first[u],first[u]=len++; } void Record() { memset(in,0,sizeof(in)); memset(vis,0,sizeof(vis)); memset(inq,0,sizeof(inq)); memset(first,-1,sizeof(first)); len=0,Totalnum=0; for(int i=0; i<26; ++i) { L[i][0].x=100,L[i][0].y=100; L[i][1].x=-1,L[i][1].y=-1; } for(int i=0; i<n; ++i) scanf("%s",mp[i]); for(int i=0; i<n; ++i)//寻找每个字母的左上角和右下角 { for(int j=0; j<m; ++j) { if(mp[i][j]=='.') continue; int val=mp[i][j]-'A'; if(!vis[val]) vis[val]=1,++Totalnum; L[val][0].x=min(L[val][0].x,i); L[val][0].y=min(L[val][0].y,j); L[val][1].x=max(L[val][1].x,i); L[val][1].y=max(L[val][1].y,j); } } } void Build()//建图 { for(int i=0; i<26; ++i) { if(!vis[i]) continue; for(int k=L[i][0].x; k<=L[i][1].x; ++k) { if(k==L[i][0].x||k==L[i][1].x)//第一行或者是最后一行需要遍历整个列 { for(int j=L[i][0].y; j<=L[i][1].y; ++j) { if(mp[k][j]=='.') continue; int val=mp[k][j]-'A'; if(val!=i&&!inq[i][val])//防止重边 { inq[i][val]=1; add_edge(i,val); ++in[val]; } } } else//否则只需遍历最小列和最大列 { if(mp[k][L[i][0].y]!='.') { int val=mp[k][L[i][0].y]-'A'; if(val!=i&&!inq[i][val]) { inq[i][val]=1; add_edge(i,val); ++in[val]; } } if(mp[k][L[i][1].y]!='.') { int val=mp[k][L[i][1].y]-'A'; if(val!=i&&!inq[i][val]) { inq[i][val]=1; add_edge(i,val); ++in[val]; } } } } } } void DFS(int len)//dfs进行拓扑排序 { if(len==Totalnum) { ans[len]='\0'; printf("%s\n",ans); return ; } for(int i=0; i<26; ++i)//从小到大字典序 { if(!vis[i]) continue; if(!in[i])//入度为0,则说明此点此时在最前面 { --in[i]; ans[len]=i+'A'; for(int j=first[i]; ~j; j=E[j].next)//它指向的点的入度-1 --in[E[j].v]; DFS(len+1); for(int j=first[i]; ~j; j=E[j].next) ++in[E[j].v]; ++in[i]; } } } int main() { while(~scanf("%d%d",&n,&m)) { Record(); Build(); DFS(0); } return 0; }
相关文章推荐
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking(DFS+拓扑排序)
- poj 1128 Frame Stacking
- POJ 1128 Frame Stacking
- POJ-1128 Frame Stacking
- POJ-1128 Frame Stacking
- poj 1128 Frame Stacking