poj1128 dfs+拓扑

http://poj.org/problem?id=1128

 

题目大意:
如图有5个9*8的区域
[拓扑排序+构图]poj <wbr>1128:Frame <wbr>Stacking

上面分别存在由相同的字母围成的长方形;
把他们依次覆盖起来,便形成了如下的图形
[拓扑排序+构图]poj <wbr>1128:Frame <wbr>Stacking

//////可以大致看出有的字母方框的字母被另外的一些字母覆盖了起来
输出从下到上被覆盖的字母的顺序,例如此图为EDABC
大致思路:这种问题稍稍思考便知道是一个拓扑排序的问题,但是真正编码后便感觉还缺了一些东西,对,就是建图!模版谁都会用,但是真正牛人就是牛在知道如何搭建使用模版的环境。如图怎么在原来杂乱无章的map基础上归纳出字母之间的上下级关系便是这道题目的重点所在。
做法是这样:
依次遍历整个map,找到一个字母后便针对这个字母,求出其所在方框的范围,并找出的其范围内的其他字母,建立指向原先字母的边。对图中所有字母重复这个过程,便得到了一个有向图,并对这个有向图拓扑排序,便得到了答案
 
 
 
 
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 char str[100];
 6 char map[100][100];
 7 bool vis[100];
 8 int in[100],edge[100][100],r,c;
 9 int lx,uy,rx,dy,num;
10 void find(int y,int x){
11     char ch=map[y][x];
12     lx=uy=10000;
13     rx=dy=-1;
14     for(int i=0;i<r;i++){
15         for(int j=0;j<c;j++){
16             if(map[i][j]==ch){
17                      if(i<uy)uy=i;
18                      if(i>dy)dy=i;
19                      if(j<lx)lx=j;
20                      if(j>rx)rx=j;
21             }
22         }
23     }
24 }
25 void buildmap(){
26     int i,j,k;
27     num=0;
28     for(i=0;i<r;i++){
29         for(j=0;j<c;j++){
30             if(map[i][j]=='.'||in[map[i][j]-'A']!=-1)continue;
31             num++;
32             in[map[i][j]-'A']=0;
33             char ch=map[i][j];
34             find(i,j);
35             for(k=lx;k<=rx;k++){
36                 if(map[uy][k]!=ch)edge[ch-'A'][map[uy][k]-'A']=1;
37                 if(map[dy][k]!=ch)edge[ch-'A'][map[dy][k]-'A']=1;
38             }
39             for(k=uy;k<=dy;k++){
40                 if(map[k][lx]!=ch)edge[ch-'A'][map[k][lx]-'A']=1;
41                 if(map[k][rx]!=ch)edge[ch-'A'][map[k][rx]-'A']=1;
42             }
43         }
44     }
45     for(i=0;i<27;i++){
46         for(j=0;j<27;j++){
47             if(edge[i][j])
48                 in[j]++;
49         }
50     }
51 }
52 void dfs(char *s,int cnt){
53     if(cnt==num){
54         printf("%s\n",str);
55         return;
56     }
57     int i,j;
58     for(i=0;i<27;i++){
59         if(in[i]==0&&!vis[i]){
60             str[cnt]=i+'A';
61             vis[i]=1;
62             for(j=0;j<27;j++){
63                 if(edge[i][j])--in[j];
64             }
65             dfs(s,cnt+1);
66             vis[i]=0;
67             for(j=0;j<27;j++){
68                 if(edge[i][j])++in[j];
69             }
70         }
71     }
72 }
73 int main(){
74     int i,j;
75     while(scanf("%d%d",&r,&c)!=EOF){
76         memset(str,0,sizeof(str));
77         memset(vis,0,sizeof(vis));
78         memset(in,-1,sizeof(in));
79         memset(edge,0,sizeof(edge));
80         for(i=0;i<r;i++)scanf("%s",map[i]);
81         buildmap();
82         dfs(str,0);
83     }
84     return 0;
85 }
View Code

 

posted @ 2015-05-17 11:09  zach96  阅读(145)  评论(0编辑  收藏  举报