poj1128 dfs+拓扑

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

题目大意:

如图有5个9*8的区域

上面分别存在由相同的字母围成的长方形;

把他们依次覆盖起来,便形成了如下的图形

//////可以大致看出有的字母方框的字母被另外的一些字母覆盖了起来

输出从下到上被覆盖的字母的顺序,例如此图为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 }

时间: 2024-10-08 06:59:36

poj1128 dfs+拓扑的相关文章

HDU3342有向图判圈DFS&amp;&amp;拓扑排序法

HDU3342 Legal or Not 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3342 题目意思:一群大牛互相问问题,大牛有不会的,会被更厉害的大牛解答,更厉害的大牛是会的东西比大牛多,但是有的时候更厉害的大牛会装弱,出来问问题,这样就被大牛解答了.这样就形成了一个圈.题目的意思就是让你在一个有向图里面判断是否存在环.我们可以通过dfs和拓扑排序两种方法. DFS的代码: //Author: xiaowuga #include <bits

hihoCoder#1185 : 连通性&#183;三 tarjan求强联通分量 缩点 dfs/拓扑排序求路径和最大值

题目链接: http://hihocoder.com/problemset/problem/1185# 题意: n个点,每个点有一个权值,m条有向边,从1出发,每走到一个点, 就吃掉这个点的草,当没有可以到达的草场或是能够到达的草场都已经被吃光了之后就要返回到1了.求最多可以吃掉多少草. 思路: 提示里面讲的挺好的 如果草场是一个强连通图,那么我们只要走到任意一点,就可以把其他所有的草场都走一遍,并且可以选择任意一个点作为终点.所以把强联通块缩成一个点 因为一个强连通块会被缩成一个点,那么我们可

[poj 1691] Painting A Board dfs+拓扑排序

Painting A Board Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3611 Accepted: 1795 Description The CE digital company has built an Automatic Painting Machine (APM) to paint a flat board fully covered by adjacent non-overlapping rectangle

图论 邻接链表存储 BFS DFS 拓扑排序

package Algorithms; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.Stack; public class Graphic { public static class Vertex{ public int num;//节点编号 public int weight;//边的权重 public Vertex next;//指向顶点的

算法导论—无向图的遍历(BFS+DFS,MATLAB)

华电北风吹 天津大学认知计算与应用重点实验室 最后改动日期:2015/8/22 无向图的存储方式有邻接矩阵,邻接链表,稀疏矩阵等. 无向图主要包括双方面内容,图的遍历和寻找联通分量. 一.无向图的遍历 无向图的遍历有两种方式-广度优先搜索(BFS)和深度优先搜索(DFS).广度优先搜索在遍历一个顶点的全部节点时,先把当前节点全部相邻节点遍历了.然后遍历当前节点第一个相邻的节点的全部相邻节点,广度优先搜索使用队列来实现.深度优先搜索在遍历当前节点的全部相邻节点时,先对当前节点的第一个相邻节点进行訪

【codeforces】【比赛题解】#915 Educational CF Round 36

虽然最近打了很多场CF,也涨了很多分,但是好久没写CF的题解了. 前几次刚刚紫名的CF,太伤感情了,一下子就掉下来了,不懂你们Div.1. 珂学的那场我只做了第一题--悲伤. 这次的Educational Round打的还可以,虽然吧没有涨分(因为我是紫色的啊). 做了前4题,后面3题也比较简单,陆续也做完了. 所以心情好,来写一篇题解! [A]花园 题意: 长度为\(k\)的线段,用若干个长度为\(a_i\)的线段,正好覆盖.(\(a_i|k\)) 给定\(n\)个\(a_i\),求出最小的\

[LeetCode] 210. Course Schedule II 课程安排II

There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] Given the total number of courses and a l

暑假集训垂死挣扎记录

7.10 Wedn 最后一天文化课hhh 小学期期末都不考了还颓什么语数外物化地 晚三机房众都恣意妄为翘掉了忙着往教室外搬书 我却在录某个野鸡英语比赛的口试?? 下午的时候找教练唠了几句觉得我还能抢救 下定决心集训的时候不颓游记不颓图不颓题解不颓代码不扯淡不带违禁品 (我有预感这即将成为我人生中为数不多的实现的flag) 听说放假前就要考5场?瑟瑟发抖.jpg 也许第二机房才适合我这样基础极差习惯没有还容易飘的辣鸡吧 补补联赛也挺好的,真不想退役啊 等过了再想省选的神仙知识吧 忽然悲伤逆流成河

CF1217D Coloring Edges 判断有无环的有向图

题意:给你一张有向图,n个点,m条边,要求同一个环里的边不可以全部都为同一种颜色.问最少要涂多少种颜色,并依次给每条边编颜色号. 思路:简单的拓扑想法,一开始我用BFS的拓扑发现一直RE3,然后我就改了个很简单的DFS拓扑的样子,用邻接表vector连接每一个点. 在我用DFS的时候发现了一个问题,比如1->2,1->3,2->3,如果访问过的都编为vis[i]=1,则误把他弄成一个环了,所以访问完之后把vis[i]的值变为2就OK了,比如刚刚那个,先访问1->2,2->3,