昨天学习了并查集,今天就做了关并查集的题目,最后学习了一些二叉树的知识。
并查集是有模板的,无非就是并和查,然后可以分别将他们进行优化为按秩合并与路径压缩。
这道题套模板就可以解决了。
#include<stdio.h>
#define N 100002
int n,m,z,x,y,pre[N];
int find(int x)
{
if(pre[x]==x)
return x;
return pre[x]=find(pre[x]);
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
pre[i]=i;
while(m--)
{
scanf("%d %d %d",&z,&x,&y);
if(z==1)
{
pre[find(x)]=find(y);
}
if(z==2)
{
if(find(x)==find(y))
printf("Y\n");
else
printf("N\n");
}
}
return 0;
}
做这道题时我被坑了,我以为只有修完一条公路才能继续修下一条,其实修公路时所有公路是可以一起修的。这道题给出的有很大的关联性,可以定义一个结构体来表示,同时输出只有一个数时,数据可以用数组表示(当有多行输出时可以不断赋值给一个变量)。需要给时间进行排序,可以用sort函数进行升序排序。从小往大处走,直到所有村庄连通起来。
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define N 10001
struct node{
int x,y,t;
};
node a[100005];
int n,m,pre[N],ran[N],ans;
bool cmp(node &a,node &b)
{
return a.t<b.t;
}
int find(int x)
{
if(pre[x]==x)
return x;
return pre[x]=find(pre[x]);
}
void join(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx==fy)
return;
if(ran[fx]<ran[fy])
pre[fx]=fy;
else
{
if(ran[fx]==ran[fy])
ran[fx]++;
pre[fy]=fx;
}
}
bool theSame(int x,int y)
{
return find(x)==find(y);
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
pre[i]=i;
ran[i]=1;
}
for(int i=1;i<=m;i++)
scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].t);
sort(a+1,a+m+1,cmp);
int num=1;
for(int i=1;i<=m;i++)
{
if(find(a[i].x)!=find(a[i].y))
{
join(a[i].x,a[i].y);
while(theSame(num,num+1))
num++;
if(num>=n)
{
printf("%d\n",a[i].t);
return 0;
}
}
}
printf("-1\n");
return 0;
}