并查集专题

洛谷P3144 [USACO16OPEN]关闭农场关闭农场
离线的反着的并查集
看看在不在一个集合内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;
int n,m;
int f[99999],a[3009][3099],b[3999];
int ans[19999];
int find(int x)
{
if(x==f[x])return x;
int fx=find(f[x]);
return f[x]=fx;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[x][y]=1;
a[y][x]=1;
}
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
for(int i=n;i>=1;i--)
{

int fx=find(b[i]);
for(int j=i;j<=n;j++)
if(a[b[i]][b[j]])
{

int fy=find(b[j]);
f[fy]=fx;
}
int w=0,fz=0;
for(int j=i;j<=n;j++)
{
fz=find(b[j]);
if(w!=fz&&w!=0) ans[i]++;
w=fz;
}
}
for(int i=1;i<=n;i++)
if(ans[i])printf("NO\n");
else printf("YES\n");
}

poj 1984导航噩梦
带权并查集
不过我就是过不了
请大佬给我找错2333
思路:
维护横坐标和纵坐标
通过输入的x-x1,y-y1
判断 父节点与父节点的距离
合并父节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;
int n,m;
int f[99999],disx[99999],disy[99999],f1[99999],f2[99999],l[94999];char d[99999];
int w[99999],r[99999],s[99999];
int abs(int x)
{
return x>0?x:-x;
}
int find(int x)
{
if(x==f[x])return x;
int fx=find(f[x]);
disx[x]+=disx[f[x]];
disy[x]+=disy[f[x]];
return f[x]=fx;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=m;i++)
{

scanf("%d%d%d",&f1[i],&f2[i],&l[i]);
cin>>d[i];
}
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{

scanf("%d%d%d",&w[i],&r[i],&s[i]);
}
int j=1;
for(int i=1;i<=m;i++)
{
int fx1=find(f1[i]);
int fx2=find(f2[i]);
if(fx1==fx2) continue;
if(d[i]=='E')
disx[f1[i]]=disx[f1[i]]-disx[f2[i]]+l[i],disy[f1[i]]=disy[f1[i]]-disy[f2[i]];
if(d[i]=='W')
disx[f1[i]]=disx[f1[i]]-disx[f2[i]]-l[i],disy[f1[i]]=disy[f1[i]]-disy[f2[i]];
if(d[i]=='N')
disy[f1[i]]=disy[f1[i]]-disy[f2[i]]+l[i],disx[f1[i]]=disx[f1[i]]-disx[f2[i]];
if(d[i]=='S')
disy[f1[i]]=disy[f1[i]]-disy[f2[i]]-l[i],disx[f1[i]]=disx[f1[i]]-disx[f2[i]];

f[fx1]=fx2;
if(s[j]==i){
fx1=find(w[j]);
fx2=find(r[j]);
if(fx1!=fx2)
{
j++;
printf("-1\n");
continue;
}
printf("%d\n",abs(disx[w[j]]-disx[r[j]])+abs(disy[w[j]]-disy[r[j]]));
j++;
}
}
}
最近的文章

模拟水题

于 继续阅读
更早的文章

优先队列

较简单的排队打水,合并果子。。。 合并序列这是一个堆的问题,就用stl里的优先队列完美搞掉有两个序列先sort一下在算出最小的a[1]+b[1]…..a[1]+b[n]为一组删掉+如a[i][j+1]放进去找最小的k个12345678910111213141516171819202122232425 …

于  优先队列 继续阅读