並查集合集
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=1e6+10;
int pre[maxn],maxx[maxn],num[maxn];
int findFather(int x)
{
int a=x;
while (x!=pre[x])
{
x=pre[x];
}
while (a!=pre[a])
{
int z=a;
a=pre[a];
pre[z]=x;
}
return x;
}
void Union(int a,int b)
{
int faA=findFather(a);
int faB=findFather(b);
if(faA!=faB)
{
pre[faA]=faB;
maxx[faB]=max(maxx[faA],maxx[faB]);
num[faB]+=num[faA];
}
}
int main()
{
int n,m;
while (~scanf("%d%d",&n,&m))
{
char str[10];
for(int i=1;i<=n;i++)
{
pre[i]=i;
num[i]=1;
maxx[i]=i;
}
int Set=n;
while (m--)
{
getchar();
int x,y;
scanf("%s",str);
if(str[0]=='u')
{
scanf("%d%d",&x,&y);
if(findFather(x)!=findFather(y))
{
Union(x, y);
Set--;
}
}
if(str[0]=='s'&&str[1]=='a')
{
scanf("%d%d",&x,&y);
if(findFather(x)==findFather(y))
{
puts("1");
}
else
puts("0");
}
if(str[0]=='n')
{
scanf("%d",&x);
printf("%d\n",num[findFather(x)]);
}
if(str[0]=='s'&&str[1]=='e')
{
printf("%d\n",Set);
}
if(str[0]=='m')
{
scanf("%d",&x);
printf("%d\n",maxx[findFather(x)]);
}
}
}
return 0;
}
題目2:(最小生成樹+並查集)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 110
int father[maxn];
struct node{
int u,v,data;
}t[maxn];
bool cmp(node a,node b)
{
return a.data<b.data;
}
int findFather(int x)
{
while (x!=father[x])
{
x=father[x];
}
return x;
}
int main()
{
int n,m;
while (~scanf("%d%d",&n,&m)&&n!=0)
{
memset(father, 0, sizeof(father));
for(int i=1;i<=m;i++)
{
father[i]=i;
}
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&t[i].u,&t[i].v,&t[i].data);
}
sort(t+1, t+1+n, cmp);
int sum=0;
for(int i=1;i<=n;i++)
{
int faA=findFather(t[i].u);
int faB=findFather(t[i].v);
if(faA!=faB)
{
father[faA]=faB;
sum+=t[i].data;
}
}
int cnt=0;
for(int i=1;i<=m;i++)
{
if(father[i]==i)
cnt++;
}
if(cnt==1)
printf("%d\n",sum);
else
printf("?\n");
}
return 0;
}
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 30010
int pre[maxn];
int p[maxn];
int num[maxn];
int FindFather(int x)
{
int a=x;
while (x!=pre[x])
{
x=pre[x];
}
while (a!=pre[a])
{
int z=a;
a=pre[a];
pre[z]=x;
}
return x;
}
void Union(int x,int y)
{
int faX=FindFather(x);
int faY=FindFather(y);
if(faX!=faY)
{
pre[faX]=faY;
num[faY]+=num[faX];
}
}
int main()
{
int m,n;
while (~scanf("%d%d",&m,&n))
{
if(m==0&&n==0)
break;
memset(num, 0, sizeof(num));
memset(pre, 0, sizeof(pre));
for(int i=0;i<m;i++)
{
pre[i]=i;
num[i]=1;
}
while (n--)
{
int t;
scanf("%d",&t);
memset(p, 0, sizeof(p));
for(int i=0;i<t;i++)
{
scanf("%d",&p[i]);
}
for(int i=0;i<t-1;i++)
{
Union(p[i], p[i+1]);
}
}
int k=FindFather(0);
printf("%d\n",num[k]);
}
return 0;
}
debug了很久,沒有想到runtime error也可能是陣列記憶體不夠大導致的
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 10010
struct node{
int u,v;
double cost;
}a[maxn],b[maxn];
int pre[maxn];
bool cmp(node a,node b)
{
return a.cost<b.cost;
}
int findFather(int x)
{
int a=x;
while (x!=pre[x])
{
x=pre[x];
}
while (a!=pre[a])
{
int z=a;
a=pre[a];
pre[z]=x;
}
return x;
}
/*int findFather(int x)
{
int r=x;
while (r!=pre[r])
r=pre[r];
pre[x]=r;
return r;
}*/
int Union(int x,int y)
{
int paA=findFather(x);
int paB=findFather(y);
if(paA!=paB)
{
/*if(paA<paB)
pre[paB]=paA;
else*/
pre[paA]=paB;
return 1;
}
else
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].u,&a[i].v);
}
for(int i=0;i<n;i++)
pre[i]=i;
int k=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
b[k].u=i;
b[k].v=j;
b[k].cost=sqrt((a[i].u-a[j].u)*(a[i].u-a[j].u)+(a[i].v-a[j].v)*(a[i].v-a[j].v));
k++;
}
}
sort(b, b+k, cmp);
int cnt=0;
double sum=0;
for(int i=0;i<k;i++)
{
if((b[i].cost<=1000&&b[i].cost>=10)&&(Union(b[i].u,b[i].v)))
{
cnt++;
sum+=b[i].cost;
}
if(cnt==n-1)
break;
}
if(cnt==n-1)
printf("%.1lf\n",sum*100);
else
printf("oh!\n");
}
return 0;
}
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 1010
int pre[maxn];
int findFather(int x)
{
int a=x;
while (x!=pre[x])
{
x=pre[x];
}
while (a!=pre[a])
{
int z=a;
a=pre[a];
pre[z]=x;
}
return x;
}
void Union(int a,int b)
{
int paA=findFather(a);
int paB=findFather(b);
if(paA!=paB)
{
pre[paA]=paB;
}
}
int main()
{
int t;
scanf("%d",&t);
int flag=0;
while (t--)
{
int n,m;
//if(flag==1)
//printf("\n");
scanf("%d%d",&n,&m);
//flag=1;
for(int i=1;i<=n;i++)
pre[i]=i;
while (m--)
{
int x,y;
scanf("%d%d",&x,&y);
Union(x, y);
}
int cnt=0;
for(int i=1;i<=n;i++)
{
if(pre[i]==i)
cnt++;
}
printf("%d\n",cnt);
}
return 0;
}
題目6:注意輸入字元吸收空格對輸出的影響,還有就是路徑壓縮過程中移動步數的變化要及時更新
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 10010
int pre[maxn];
int num[maxn];
int cha[maxn];
/*int findFather(int x)
{
int a=x;
while (x!=pre[x])
{
x=pre[x];
}
while (a!=pre[a])
{
int z=a;
a=pre[a];
pre[z]=x;
}
return x;
}*/
int findFather(int x)
{
if(x!=pre[x])
{
int t=pre[x];
pre[x]=findFather(pre[x]);
cha[x]+=cha[t];//維護移動陣列
return pre[x];
}
return x;
}
void Union(int a,int b)
{
int pA=findFather(a);
int pB=findFather(b);
if(pA!=pB)
{
//if(pA<pB)
//{
pre[pA]=pB;
num[pB]+=num[pA];
cha[pA]++;
//}
//else
//{
//pre[pB]=pA;
//num[pA]+=num[pB];
//}
}
}
int main()
{
int t;
scanf("%d",&t);
int cnt=1;
while (t--)
{
int n,q;
scanf("%d%d",&n,&q);
printf("Case %d:\n",cnt++);
for(int i=1;i<=n;i++)
{
pre[i]=i;
num[i]=1;
cha[i]=0;
}
while (q--)
{
char c;//[5];
int x,y;
getchar();
scanf("%c",&c);
//getchar();
if(c=='T')
{
scanf("%d %d",&x,&y);
Union(x, y);
//++cha[x];
//cha[y]++;
}
if(c=='Q')
{
scanf("%d",&x);
int k=findFather(x);
printf("%d %d %d\n",k,num[k],cha[x]);
}
}
}
return 0;
}
題目7:還有為什麼是聯絡縱座標沒有搞清楚,待考慮
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 500010
int pre[maxn];
struct node{
int x,y;
}t[maxn];
bool vis[maxn];
int findFather(int x)
{
if(x==pre[x])
return x;
else
{
int F=findFather(pre[x]);
pre[x]=F;
return F;
}
}
/*int findFather(int x)
{
int p=x;
while(p!=pre[p]) p=pre[p];
int q;
while(pre[x]!=p)
{
q=pre[x];
pre[x]=p;
x=q;
}
return p;
}*/
void Union(int a,int b)
{
int faA=findFather(a);
int faB=findFather(b);
if(faA!=faB)
pre[faA]=faB;
}
bool cmp(node a,node b)
{
if(a.x!=b.x)
return a.x>b.x;
else
return a.y<b.y;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(vis, 0, sizeof(vis));
for(int i=1;i<=50000;i++)
{
pre[i]=i;
}
for(int i=0;i<n;i++)
{
scanf("%d%d",&t[i].x,&t[i].y);
vis[t[i].y]=1;
}
sort(t, t+n, cmp);
int prex=-1;
int prey=-1;
for(int i=0;i<n;i++)
{
if(t[i].x!=prex)
{
prex=t[i].x;
prey=t[i].y;
}
else
{
Union(prey, t[i].y);//同一橫軸已經統一根,現在就是統一豎軸,所以最後求的是y
}
}
int cnt=0;
for(int i=1;i<=50000;i++)
{
if(vis[i])
{
if(pre[i]==i)
cnt++;
}
}
if(cnt==1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
相關文章
- 並查集題目合集並查集
- 並查集到帶權並查集並查集
- 【並查集】【帶偏移的並查集】食物鏈並查集
- 並查集(一)並查集的幾種實現並查集
- 3.1並查集並查集
- 並查集(小白)並查集
- 並查集(Union Find)並查集
- 並查集應用並查集
- The Door Problem 並查集並查集
- 並查集練習並查集
- 並查集的使用並查集
- 並查集—應用並查集
- 寫模板, 並查集。並查集
- 並查集跳躍並查集
- 各種並查集並查集
- 食物鏈(並查集)並查集
- 並查集(二)並查集的演算法應用案例上並查集演算法
- The Suspects-並查集(4)並查集
- [leetcode] 並查集(Ⅰ)LeetCode並查集
- [leetcode] 並查集(Ⅱ)LeetCode並查集
- [leetcode] 並查集(Ⅲ)LeetCode並查集
- 並查集演算法並查集演算法
- 並查集深度應用並查集
- 【轉】種類並查集並查集
- 並查集java實現並查集Java
- 並查集-Java實現並查集Java
- 並查集以及應用並查集
- 並查集的應用並查集
- 暢通工程(並查集)並查集
- (Day3)並查集並查集
- 並查集擴充套件並查集套件
- 簡單易懂的並查集演算法以及並查集實戰演練並查集演算法
- 關於並查集問題並查集
- 並查集的應用2並查集
- 並查集の進階用法並查集
- 並查集(UnionFind)技巧總結並查集
- Wireless Network(並查集(裸))並查集
- 並查集應用總結並查集