题意:给出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;
}