前言
大家好呀,周六啦,周末当然是要代码+音乐啊(刚打完王者😁😁),记录下昨晚寝室的happy:回味无穷的美食😍+惊悚电影🤪+快乐五排无限上分😁.
好啦,这篇博客是想再复习下昨天的算法课内容.
✈️✈️问题:
问题:有n个城市,通过输入俩个数a,b,表示a->b是联通的,求最后联通的个数。
✈️✈️解决:
开一个数组father,先初始化:每个数组的下标与它的值相等father[i]=i,
假如输入1和3,表示1城市到3城市是联通的(1->3),先判断father[i]是否等于i,如果相等就将下标为1的值修改为3,即father[1]=3;否则根据father[i]存的值查找数组下标为father[i]的数,一直到查到father[i]=i,再father[i]=b;
假如再输入1和5,表示1城市到5城市是联通的(1->5).还是一样先判断father[i]是否等于i,显然不等,就查找father[1]的值,值为3,所以查找father[3],再判断father[3]是否等于3,这里是等于,所以将father[3]赋值为5,否则继续查找。
当所有的用例输入完后,father数组的每个元素也都有修改后的值了,这时候,遍历数组,记录father[i]仍然等于i的个数,得到的就是答案.
✈️✈️查函数代码(Find)
int Find(int x)
{
int t = x;
while (t != father[t])
{
t = father[t];
}
return t;
}
✈️✈️并函数代码(Union)
void Union(int x, int y)
{
int Ax = Find(x);
int Ay = Find(y);
if (Ax != Ay)
{
father[Ax] = Ay;
}
}
下面引入俩道题,先看杭电1213:
✈️✈️杭电1213:
题意:有人过生日,邀请朋友参加,大家一起吃饭。不认识的人不呆在一桌不好。如果A认识B,B认识C,那么A也被认为是和C认识,能够待在同一桌。
问题:最少要多少张桌子?
这个问题其实转化过来就是问有多少个联通的。
代码段:
#include<iostream>
using namespace std;
const int N = 1e3 + 10;
int father[N];
int Find(int x)
{
int t = x;
while (t != father[t])
{
t = father[t];
}
return t;
}
void Union(int x, int y)
{
int Ax = Find(x);
int Ay = Find(y);
if (Ax != Ay)
{
father[Ax] = Ay;
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
for (int i = 1; i < n + 1; i++)
{
father[i] = i;
}
while (m--)
{
int x, y;
cin >> x >> y;
Union(x, y);
}
int count = 0;
for (int i = 1; i < n+1; i++)
{
if (father[i] == i)
{
count++;
}
}
cout << count << endl;
}
return 0;
}
✈️✈️杭电1232:
题意:要使整个图连通,至少还需几条边?
答案就是连通的个数减去1
代码和上面是一样的,最后答案为count-1;
😜😜最后的话
好啦,这篇博客到此结束啦,
该去吃中饭咯😃😃,下午有节选修课🤒🤒,今晚要学AVL啦❤️