通过几道例题简单阐述一下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. 网络方案 & HTTP状态码

    在iOS中,常见的发送HTTP请求的方案包括: 苹果官方 名称 说明 NSURLConnection iOS 2.0 推出,用法简单,最古老最经典最直接的一种方案 NSURLSession iOS 7 ...

  2. vim does not map customized key?

    it is a long time confusing me that why my customized key map in vim does not work? Some vim configu ...

  3. Mastering Web Application Development with AngularJS 读书笔记(三)

    第一章笔记 (三) 一.Factories factory 方法是创建对象的另一种方式,与service相比更灵活,因为可以注册可任何任意对象创造功能.例如: myMod.factory('notif ...

  4. 【转载】VC维的来龙去脉

    本文转载自 火光摇曳 原文链接:VC维的来龙去脉 目录: 说说历史 Hoeffding不等式 Connection to Learning 学习可行的两个核心条件 Effective Number o ...

  5. [译]Mongoose指南 - 中间件

    中间件是一些函数, 当document发生init, validate, save和remove方法的时候中间件发生. 中间件都是document级别的不是model级别的. 下面讲讲两种中间件pre ...

  6. 工具介绍 - NimbleText

    非常实用的工具, 即使不是程序员也有必要掌握这个简单的小工具. 这个工具有桌面版和在线版两个版本. 桌面版地址: http://nimbletext.com/ 在线版地址: http://nimble ...

  7. 清北暑假模拟day1 爱

    /* 水题 */ #include<iostream> #include<cstdio> #include<string> #include<cstring& ...

  8. PHP多态的理解

    多态性的一般定义为:同一个操作作用于不同的类的实例,将产生不同的执行结果.也即不同类的对象收到相同的消息时,将得到不同的结果.在实际的应用开发中,采用面向对象中的多态主要在于可以将不同的子类对象都当作 ...

  9. Knockout.Js案例一Introduction

    </strong></p> <p>Last name: <strong data-bind="text:lastName ">tod ...

  10. maven项目如何使用jetty启动?

    1.在pom.xml文件中插入下面的片段 <build> <plugins> <plugin> <groupId>org.eclipse.jetty&l ...