通过几道例题简单阐述一下DFS的相关题型


ZOJ2412-Farm Irrigation

  直观的DFS题型,稍加变化,记录好四个方向上的通路就能够做出来

  题目和接水管类似,问最少要灌溉几次,即求解最少有多少个连通子图。

  

 //和接水管游戏类似,将相应水管通路标记清晰即可
//Time:0Ms Memory:270K
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAX 55
#define OPPOSITE(x) ((x + 2) % 4) //x的相反位置
#define MAP(x,y) (map[x][y] - 'A') //水管序列
int row, col;
char map[MAX][MAX];
bool v[MAX][MAX];
int mov[][] = { {, }, {, }, {, -}, {-, } }; //东南西北
bool face[][] = { //face[i][j] : 在i方向上第j个水管是否有通路
{ ,,,,,,,,,, }, //东
{ ,,,,,,,,,, }, //南
{ ,,,,,,,,,, }, //西
{ ,,,,,,,,,, } //北
};
void dfs(int x,int y)
{
v[x][y] = true;
for (int i = ; i < ; i++)
{
int tx = x + mov[i][];
int ty = y + mov[i][];
if (face[i][MAP(x,y)] && tx >= && tx < row && ty >= && ty < col) //该水管相应对接方向有通路
{
if (!v[tx][ty] && face[OPPOSITE(i)][MAP(tx,ty)]) //对接水管相应方向有通路
dfs(tx, ty);
}
}
}
int main()
{
while (scanf("%d%d", &row, &col), row != - && col != -)
{
memset(v, false, sizeof(v));
for (int i = ; i < row; i++)
scanf("%s", map[i]);
int times = ;
for (int i = ; i < row; i++)
for (int j = ; j < col; j++)
{
if (!v[i][j]) {
times++;
dfs(i, j);
}
}
printf("%d\n", times);
}
return ;
}

ZOJ1008-Gnome Tetravex

  看起来不像个搜索题,初看可能会以为需要枚举之类的,但是题中方块的各状态需要记录,在匹配失败时需要回退,因此是一道DFS题型。

  大致的解题思路就是先枚举0行0列的方块,再依据此方块固定下一个方块,以此类推,出现不能匹配时回退。

  虽然规模最大只有5,但是总方块数25个在DFS中也不可小觑,如果用纯DFS来做,时间度最坏可以达到O((n^2)!),因此剪枝或其他优化是必须的(只要数据不够水),我在超时后看了很多博客的解题报告(想不到了= =),就该题数据而言最好的优化方法是去重,即将相同方块合在一起,以减少DFS的分支数,但是我总觉得这么做挺奇怪的。。。虽然在大数据下,此题去重很有效果(数字在0-9,因此方块重复概率 < 1/2500),但是此题拿小数据故意出多组重复方块,不得不让人怀疑其心不善...

  

  另外的剪枝方法,也有很多比较有效,但对此题没有太大帮助。

    例如:记录各方向上各数字的个数,在匹配时动态增删,如果已经固定的方块需要的对应数字的数量缺失,那么就可以直接回退,剪枝效果在少量随机数据情况下比较好。

    

 //去重就不会超时了,但这个优化实在是...让人感到很意外
//Time:2100ms Memory:272K
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std; #define MAX 28 int n, m;
int sq[MAX][]; //上右下左
int board[MAX]; //棋盘上对应位置的square
int v[MAX]; //记录同类sq未被使用的数量 bool dfs(int num)
{
if (num == n*n)
return true;
//找出可以充当第num个方块的i方块
for (int i = ; i < m; i++)
{
if (!v[i]) continue; //没有未固定方块
if (num % n && sq[i][] != sq[board[num - ]][]) continue; //非第一列+不匹配
if (num / n && sq[i][] != sq[board[num - n]][]) continue; //非第一行+不匹配 v[i]--;
board[num] = i;
if (dfs(num + )) return true;
else v[i] ++;
}
return false;
} int main()
{
int t = ;
while (scanf("%d", &n), n)
{
if (t) printf("\n"); memset(v, , sizeof(v));
memset(board, , sizeof(board));
m = ;
for (int i = ; i < n*n; i++)
{
int u, r, d, l;
scanf("%d%d%d%d", &u, &r, &d, &l);
//查重
bool flag = false;
for (int j = ; j < m; j++)
{
if (u == sq[j][] && r == sq[j][] && d == sq[j][] && l == sq[j][])
{
v[j]++;
flag = true;
break;
}
}
if (!flag) {
sq[m][] = u; sq[m][] = r; sq[m][] = d; sq[m][] = l;
v[m++] ++;
}
} if (dfs()) printf("Game %d: Possible\n", ++t);
else printf("Game %d: Impossible\n", ++t);
} return ;
}

ACM/ICPC 之 DFS范例(ZOJ2412-ZOJ1008)的更多相关文章

  1. ACM/ICPC 之 DFS+SPFA-贪心+最短路(POJ2679)

    //POJ2679 //DFS+SPFA+邻接表 //只能走每个点费用最小的边,相同则需保证距离最短 //求最小费用及最短距离 //Time:47Ms Memory:900K #include< ...

  2. ACM/ICPC 之 DFS求解欧拉通路路径(POJ2337)

    判断是欧拉通路后,DFS简单剪枝求解字典序最小的欧拉通路路径 //Time:16Ms Memory:228K #include<iostream> #include<cstring& ...

  3. ACM/ICPC 之 DFS求解欧拉回路+打表(POJ1392)

    本题可以通过全部n位二进制数作点,而后可按照某点A的末位数与某点B的首位数相等来建立A->B有向边,以此构图,改有向图则是一个有向欧拉回路,以下我利用DFS暴力求解该欧拉回路得到的字典序最小的路 ...

  4. ACM/ICPC 之 Floyd范例两道(POJ2570-POJ2263)

    两道以Floyd算法为解法的范例,第二题如果数据量较大,须采用其他解法 POJ2570-Fiber Network //经典的传递闭包问题,由于只有26个公司可以采用二进制存储 //Time:141M ...

  5. ACM/ICPC 之 Prim范例(ZOJ1586-POJ1789(ZOJ2158))

    两道Prim解法范例题型,简单的裸Prim,且两题相较以边为重心的Kruskal解法而言更适合以点为重心扩展的Prim解法. ZOJ1586-QS Network 题意:见Code 题解:直接的MST ...

  6. ACM/ICPC 之 Kruskal范例(ZOJ1203-POJ1861(ZOJ1542))

    两道最小生成树范例,Kruskal解法-以边为主体扩展最小生成树,需要利用并查集. ZOJ1203-Swordfish 题意:求n个给定平面坐标的城市中的一条平面距离上的最短路长(保留两位小数) 题解 ...

  7. ACM/ICPC 之 SPFA范例两道(POJ3268-POJ3259)

    两道以SPFA算法求解的最短路问题,比较水,第二题需要掌握如何判断负权值回路. POJ3268-Silver Cow Party //计算正逆最短路径之和的最大值 //Time:32Ms Memory ...

  8. ACM/ICPC 之 BFS范例(ZOJ2913-ZOJ1136(POJ1465))

    通过几道经典BFS例题阐述BFS思路 ZOJ2913-Bus Pass 题意:找一个center区域,使得center到所有公交线路最短,有等距的center则输出id最小的. 题解:经典的BFS,由 ...

  9. hduoj 4707 Pet 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4707 Pet Time Limit: 4000/2000 MS (Java/Others)    Memory ...

随机推荐

  1. maven 错误解决办法集

    一.mavenFailed to execute goal org.apache.maven.plugins:maven-surefire-plugin解决方法 1.测试代码没有获得通过,可以尝重命名 ...

  2. uname是什么?

    uname= unix +name, 是指unix 这个操作系统的 名字, 包括 主机名, 内核版本 架构 平台名称等等

  3. Java实验1-文件IO

    目标:掌握Java类的创建,Java  I/O操作,Java集合类的使用等 内容: 王老师非常喜欢读书,为了便于查阅,他每次买书回家后就在笔记本上登记每本书的详细信息(书名.作者.出版社.出版日期.价 ...

  4. 成功的背后!(给所有IT人)

    转载:来自CSDN第一名博主:http://blog.csdn.net/phphot/article/details/2187505 成功的背后,有着许多不为人知的故事,而正是这些夹杂着泪水和汗水的过 ...

  5. caller和callee

    我们先来看下caller. caller:返回一个对函数(该函数调用了当前函数)的引用. functionName.caller:functionName对象是所执行函数的名称. 说明 对于函数来说, ...

  6. glusterFS的常用命令 (转)

    1.       启动/关闭/查看glusterd服务 # /etc/init.d/glusterd start # /etc/init.d/glusterd stop # /etc/init.d/g ...

  7. QT连接Linux mysql注意

    windows: #define MYSQLDB "QMYSQL"#define MYSQLDB_HOSTNAME "192.168.228.168"#defi ...

  8. HDOJ 4717 The Moving Points

    The Moving Points Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  9. canvas对象arc函数的使用-遁地龙卷风

    (-1)写在前面 我用的是chrome49 <canvas id="lol" height="300"></canvas> (1)详细介 ...

  10. 高性能Java网络框架 MINA

    Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...