【DFS训练】wiki题目之 传话

题目:http://wikioi.com/problem/1506/

马上就要比赛了,应当来一些集训才是。集训的话,我觉得熟悉算法就好了。

目前掌握的算法虽然不多,不过就我的准备情况而言,算是不错的了,接下来的时间,我觉得就把这些个经典的算法巩固熟练就好了。

今天拿来开刀的题目,虽然解出来了,但是一组数据超时了。额,目前看来还是没有什么优化的手段了。

不过在优化的过程中,我深刻的体会到判断语句是非常耗时的,944ms的计算,多个判断就多到了1001ms。

开始运行一直不知道是哪里出了问题,后来经过调试发现了问题。

一般调试的话,先在程序中插入输出语句来看比较好。不过也可以直接进入debug模式。然后再在最可能的位置插入断点调试。


两个问题的话,一个是判断成功的结束条件弄错了,另一个是没有记录遍历过的节点,导致死循环。

看来在DFS中,结束条件和遍历节点这两个地方是十分容易出错的呀。

上代码好了。不是最优的,我是按照一般的DFS思路来的。

#include <stdio.h>
#include <stdlib.h>

// 全体都-1,1->0 
//1、初始化。
//二维关系矩阵,访问列表记录 
int maz[1000*1000];
int vis[1000*1000] = {0};
int row;
struct no
{
	int i;
	int j;	
};

int dfs(struct no start,int tofind)
{
	
	int i;
	struct no tmp;
	//问题在这里面= = 

	for(i=0 ; start.j+i < row ; i++)
	{
		//2、达到目的的终止条件 
		if(maz[start.i*row+start.j+i] == tofind)
		{
			return 1;	
		}
		//没有访问过、  而且有联系 
		//对于环状的联系会成死循环 
		//3、没有访问过,而且邻接的节点 
		if( vis[start.i*row + start.j+i] != 1 && maz[start.i*row + start.j+i] != -1)
		{
			vis[start.i*row + start.j+i] = 1;
			tmp.i = start.j+i;
			tmp.j = 0;
			if (dfs(tmp, tofind) == 1)
			{
				return 1;	
			}
			
		}	
	}
	return 0;
}

void init()
{
	int n;
	scanf("%d%d",&row,&n);
	int i,j;
	for(i=0 ; i<row ; i++)
	{
		for(j=0 ; j<row ;j++)
		{
			maz[i*row+j] = -1;	
		}
	}
	while(n--)
	{
		scanf("%d%d",&i,&j);
		maz[(i-1)*row+(j-1)] = j-1;
		//printf("%dclear\n",n);
	}

}


void clear()
{
	int j,k;
	for(k=0 ; k<row; k++)
	{
		for(j=0 ; j<row; j++)
		{
				vis[k*row+j] = 0;	
		}	
	}	
}


int main()
{
	init();
	int i;
	struct no st;
	int j;
	for(i=0 ; i< row ;i++)
	{
		st.i = i;
		st.j = 0;
		if(dfs(st,i) == 1)
		{
			printf("T\n");
		}
		else printf("F\n");
		clear();
	}

	return 0;	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值