参考:http://blog.csdn.net/u013519475/article/details/18517207#
题意:在一个n*n的棋盘中放棋子,有m个操作,操作有 两种
C a b v :在(x,y)上放一个棋子,棋子的价值为v(保证这个位置之前没有放过棋子)
Q a b :查询与(a,b)相连的棋子中的最大价值 上下左右为相连
用并查集。开个一维数组,将二维的坐标压到一维,这样,然后用并查集就行了。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
const int maxn = 1005;
int f[5][5]={{1,0},{0,1},{-1,0},{0,-1}};
int vis[maxn][maxn];
int n,m;
struct node
{
int parent;
int v;
}dis[maxn*maxn];
int findf(int k)
{
int r,j;
r=k;
while(r!=dis[r].parent)
r=dis[r].parent;
j=k;
while(j!=r)
{
int temp=dis[j].parent;
dis[j].parent=r;
j=temp;
}
return r;
}
char s[5];
void init()
{
for(int i=0;i<=n*n;i++){
dis[i].parent=i;
dis[i].v=0;
}
memset(vis,0,sizeof(vis));
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
init();
for(int i=0;i<m;i++)
{
scanf("%s",s);
if(s[0]=='C')
{
int x,y,v;
scanf("%d %d %d",&y,&x,&v);
x--,y--;
dis[y*n+x].v=v;
vis[y][x]=1;
for(int i=0;i<4;i++)
{
int xx=x+f[i][0];
int yy=y+f[i][1];
if(xx>=0&&xx<n&&yy>=0&&yy<n&&vis[yy][xx])
{
int a=y*n+x;
int b=yy*n+xx;
int root1=findf(a);
int root2=findf(b);
dis[root2].v=max(dis[root1].v,dis[root2].v);//这个并不是max(v,..)
dis[root1].parent=root2;
}
}
}
else if(s[0]=='Q')
{
int x,y;
scanf("%d %d",&y,&x);
x--,y--;
int root=findf(y*n+x);
if(dis[root].v==0) printf("-1\n");
else printf("%d\n",dis[root].v);
}
}
}
return 0;
}
注意x和y。。不要弄反了,然后就是上面代码的标注部分