Time Limit: 10000MS | Memory Limit: 65536K | |
Total Submissions: 9181 | Accepted: 3857 |
Description
In the process of repairing the network, workers can take two kinds of operations at every moment, repairing a computer, or testing if two computers can communicate. Your job is to answer all the testing operations.
Input
1. "O p" (1 <= p <= N), which means repairing computer p.
2. "S p q" (1 <= p, q <= N), which means testing whether computer p and q can communicate.
The input will not exceed 300000 lines.
Output
Sample Input
4 1 0 1 0 2 0 3 0 4 O 1 O 2 O 4 S 1 4 O 3 S 1 4
Sample Output
FAIL SUCCESS
Source
前面受前几天一道网络赛的题目影响,一直以为要用FLOYED去更新
后来发现是并查集
但对于并查集合并的形式没想清楚,还是里面套了个2重循环
后来才恍然大悟,用了并查集以后,不需要用2重循环,因为只要能和X在一个集合的元素,都会因为X而合并到一个集合
WA了好几次啊,悲剧
#include<cstdio>
#include<cstring>
int n,d,p[1010];
bool vis[1010];
int map[1010][1010];
struct node
{
int x,y;
}a[1010];
void init()
{
for(int i=1;i<=n;i++) p[i]=i;
}
int getfather(int x)
{
if(x!=p[x]) p[x]=getfather(p[x]);
return p[x];
}
void Union(int a,int b)
{
a=getfather(a);
b=getfather(b);
p[a]=b;
}
int cal(int i,int j)
{
return((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
}
int main()
{
scanf("%d%d",&n,&d);
d=d*d;
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
init();
for(int i=1;i<n;i++)
for(int j=i;j<=n;j++)
if(i==j) map[i][j]=map[j][i]=0;
else map[i][j]=map[j][i]=cal(i,j);
char str[10];
while(scanf("%s",str)!=EOF)
{
if(str[0]=='O')
{
int x;
scanf("%d",&x);
if(!vis[x])
{
vis[x]=true;
int a=getfather(x);
for(int i=1;i<=n;i++)
if(i!=x&&vis[i]&&(getfather(i)==a || map[i][x]<=d)) Union(i,x);
}
}
else
{
int x,y;
scanf("%d%d",&x,&y);
if(vis[x]&&vis[y])
{
int a=getfather(p[x]);
int b=getfather(p[y]);
if(a==b) printf("SUCCESS/n");
else printf("FAIL/n");
}
else printf("FAIL/n");
}
}
return 0;
}