目录
P3144 [USACO16OPEN]Closing the Farm S
P6121 [USACO16OPEN]Closing the Farm G
P5092 [USACO04OPEN]Cube Stacking (带权并查集)
P2949 [USACO09OPEN]Work Scheduling G
P2814 家谱
#include <bits/stdc++.h>
using namespace std;
int len, cnt, father, fa[50010];
string s;
map<string, int> m;
string a[50010];
int find(int x)
{
if(fa[x]==x){
return x;
}
else return fa[x]=find(fa[x]);
}
int main()
{
while(cin>>s && s[0]!='$'){
string name="";
len=s.length();
for(int i=1; i<len; ++i){
name+=s[i];
}
if(s[0]=='#'){
if(m.count(name)!=0){
father=m[name];
continue;
}
cnt++;
m[name]=cnt;
a[cnt]=name;
fa[cnt]=cnt;
father=cnt;
}
else if(s[0]=='+'){
if(m.count(name)!=0){
int id=m[name];
fa[id]=father;
continue;
}
cnt++;
m[name]=cnt;
a[cnt]=name;
fa[cnt]=father;
}
else if(s[0]=='?'){
int id=m[name];
cout << name << " " << a[find(id)] << endl;
}
}
return 0;
}
P1955 [NOI2015] 程序自动分析
并查集和map(哈希)结合起来的一道好题
#include <bits/stdc++.h>
using namespace std;
int t, n, fa[1000010], cnt;
bool flag;
map<int, int> m;
struct node
{
int x, y, z;
}limit[1000010];
bool cmp(node a, node b)
{
return a.z>b.z;
}
int find(int x)
{
if(fa[x]==x){
return x;
}
return fa[x]=find(fa[x]);
}
void merge(int u, int v)
{
int fu=find(u);
int fv=find(v);
if(fu!=fv){
fa[fu]=fv;
}
}
int main()
{
scanf("%d", &t);
while(t--){ //10
scanf("%d", &n);
m.clear();
flag=true;
for(int i=1; i<=n; ++i){ //1e6
scanf("%d %d %d", &limit[i].x, &limit[i].y, &limit[i].z);
}
sort(limit+1, limit+n+1, cmp); //1e6*20
for(int i=1; i<=n; ++i){ //1e6
int u=limit[i].x;
int v=limit[i].y;
int e=limit[i].z;
if(m.count(u)==0){
cnt++;
fa[cnt]=cnt; //初始化并查集
m[u]=cnt; //将大范围的整数u映射成小范围的整数cnt
}
if(m.count(v)==0){
cnt++;
fa[cnt]=cnt; //初始化并查集
m[v]=cnt; //将大范围的整数v映射成小范围的整数cnt
}
if(e==1){ //合并
merge(m[u], m[v]);
}
else{ //判断u和v的祖先是否相同
int fu=find(m[u]);
int fv=find(m[v]);
if(fu==fv){
flag=false;
printf("NO\n");
break;
}
}
}
if(flag){
printf("YES\n");
}
}
return 0;
}
P2256 一中校运会之百米跑 (并查集结合map)
#include <bits/stdc++.h>
using namespace std;
const int N=20010;
int n, m, k, fa[N], u, v, fu, fv;
string name1, name2;
map<string, int> asd;
int find(int x)
{
if(fa[x]==x){
return x;
}
else{
return fa[x]=find(fa[x]);
}
}
void merge(int u, int v)
{
int fu=find(u);
int fv=find(v);
fa[fu]=fv;
}
int main()
{
scanf("%d %d", &n, &m);
for(int i=1; i<=n; ++i){
fa[i]=i;
cin >> name1;
asd[name1]=i;
}
while(m--){
cin >> name1 >> name2;
u=asd[name1];
v=asd[name2];
merge(u, v);
}
scanf("%d", &k);
while(k--){
cin >> name1 >> name2;
u=asd[name1];
v=asd[name2];
if(find(u)==find(v)){
printf("Yes.\n");
}
else{
printf("No.\n");
}
}
return 0;
}
P3144 [USACO16OPEN]Closing the Farm S
并查集倒着做合并, AC
#include <bits/stdc++.h>
using namespace std;
int

本文通过多个编程竞赛题目,展示了并查集在处理各种问题中的应用,如家谱构建、程序分析、棋盘游戏、数组修改等,同时结合了哈希表和路径压缩等技巧,深入探讨了并查集的实现策略。
最低0.47元/天 解锁文章
2139

被折叠的 条评论
为什么被折叠?



