Poj 1826 The Best Farm (floodfill + Hash)

本文介绍了一个利用Hash表和Floodfill模型解决四连通块最大权值问题的方法,通过实例分析了如何在较大坐标范围内高效求解,并讨论了BFS和DFS两种搜索算法的性能对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给出N个单位方块的坐标以及权值,求出其中所有四连通块中最大的权值和

思路:很基础的floodfill模型,就是这次坐标范围比较大,不能直接存。使用了hash来处理。网上还有排序等其他方法。

BFS速度较慢,1500ms左右,DFS 500ms左右

关于Hash时模值为什么选择素数这里有一篇分析,涨姿势了:为什么一般hashtable的桶数会取一个素数_罗自荣_新浪博客

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define max(x,y) ((x)>(y)?(x):(y))

const int N=200020;
const int prime=273899;

struct Node
{
	int x,y,val;
	int id,next;
}edges[N];

int n,head[prime+30];
bool visit[N];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};

int Hash (int x,int y)
{
	__int64 temp,xx,yy;
	xx=x*x-y;
	yy=y*y-x;
	temp=((xx+yy)%prime)+prime;
	return (int)(temp%prime);
}

void Add (int id)
{
	int key=Hash(edges[id].x,edges[id].y);
	edges[id].next=head[key];
	head[key]=id;
}

int Find (int x,int y)
{
	int key,i;
	key=Hash(x,y);
	for (i=head[key];i!=-1;i=edges[i].next)
		if (edges[i].x==x && edges[i].y==y)
			return edges[i].id;
	return -1;
}

__int64 DFS (int id)
{
	__int64 ans;
	Node cur;
	visit[id]=true;
	cur=edges[id];
	ans=cur.val;
	for (int i=0;i<4;i++)
	{
		int xx=cur.x+dx[i];
		int yy=cur.y+dy[i];
		id=Find(xx,yy);
		if (id!=-1 && visit[id] == false)
			ans+=DFS(id);
	}
	return ans;
} 

__int64 BFS (int id)
{
	queue<Node> Q;
	Node cur;
	__int64 ans=edges[id].val;

	visit[id]=1;
	Q.push(edges[id]);
	while (!Q.empty())
	{
		cur=Q.front();
		Q.pop();

		for (int i=0;i<4;i++)
		{
			int xx=cur.x+dx[i];
			int yy=cur.y+dy[i];
			id=Find(xx,yy);
			if (id!=-1 && visit[id]==false)
			{
				visit[id]=1;
				ans+=edges[id].val;
				Q.push(edges[id]);
			}
		}
	}
	return ans;
}

int main ()
{
	int i;
	__int64 ans,temp;
	while (scanf("%d",&n) && n)
	{
		memset(head,-1,sizeof(head));
		memset(visit,false,sizeof(visit));
		ans=-1;
		temp=0;
		for (i=1;i<=n;i++) 
		{
			scanf("%d%d%d",&edges[i].x,&edges[i].y,&edges[i].val);
			edges[i].id=i;
			Add(i);
		}
		for (i=1;i<=n;i++)
			if (visit[i]==false)
			{
//				temp=BFS(i);
				temp=DFS(i);
				ans=max(ans,temp);
			}
		printf("%I64d\n",ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值