题目:来自acwing的并查集使用
一共有 n 个数,编号是 1∼n
,最开始每个数各自在一个集合中。
现在要进行 m
个操作,操作共有两种:
M a b
,将编号为 a和 b
Q a b
,询问编号为 a输入格式
第一行输入整数 n
和 m。
接下来 m
行,每行包含一个操作指令,指令为 M a b
或 Q a b
中的一种。
输出格式
对于每个询问指令 Q a b
,都要输出一个结果,如果 a
在同一集合内,则输出 Yes
,否则输出 No
。
每个结果占一行。
数据范围
1≤n,m≤105
输入样例:
4 5
M 1 2
M 3 4
Q 1 2
Q 1 3
Q 3 4
输出样例:
Yes
No
Yes
#include
int p[100100];
using namespace std;
int found(int x) {
if (x != p[x])//如果我自己不是自己的祖先就是说我还没有找到我的老板
p[x] = found(p[x]);//就去找我的老板的老板
return p[x];
}
int main() {
int n, m;
cin >> n >> m;
for (int i = 0; i <= n; i++)
p[i] = i;//先假设我自己是我自己老板
while (m--) {
char s[5];
int a, b;
cin >> s >> a >> b;
if (s[0] == 'M')
p[found(a)] = found(b);//然后把a的节点接到b祖先上
else {
if (found(a) == found(b))//判断他的祖先是不是相等得
cout << "Yes" << endl;
else
cout << "No" << endl;
}
}
}
给定一个包含 n 个点(编号为 1∼n
)的无向图,初始时图中没有边。
现在要进行 m
个操作,操作共有三种:
C a b
,在点 a和点 b 之间连一条边,a 和 b
Q1 a b
,询问点 aQ2 a
,询问点 a输入格式
第一行输入整数 n
和 m
。
接下来 m
行,每行包含一个操作指令,指令为 C a b
,Q1 a b
或 Q2 a
中的一种。
输出格式
对于每个询问指令 Q1 a b
,如果 a
和 b
在同一个连通块中,则输出 Yes
,否则输出 No
。
对于每个询问指令 Q2 a
,输出一个整数表示点 a
所在连通块中点的数量
每个结果占一行。
数据范围
1≤n,m≤105
输入样例:
5 5
C 1 2
Q1 1 2
Q2 1
C 2 5
Q2 5
输出样例:
Yes
2
3
#include
using namespace std;
int p[100010];
int cnt[100010];
int find(int x) {//找到父亲的节点
if (p[x] != x)//如果没有找到他的节点
p[x] = find(p[x]);//那就去找他节点的节点
return p[x];
}
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
p[i] = i;
cnt[i] = 1;
}
while (m--) {
char s[5];
cin >> s;
if (s[0] == 'C') {
int a, b;
cin >> a >> b;
a = find(a), b = find(b);//只可以写成这种
if ((a) != (b)) {//这里有一个容易错的地方,
//就是不考虑a==b,然后还继续加了节点就是错误
p[(a)] = (b);
cnt[(b)] += cnt[(a)];
}
} else if (s[1] == '1') {
int a, b;
cin >> a >> b;
if (p[find(a)] == p[find(b)])//判断他们的父亲是否相同
printf("Yes\n");
else
cout << "No" << endl;
} else {
int a;
cin >> a;
cout << cnt[find(a)] << endl;//找到他父亲的节点,然后输出底下到底
//多少个好大儿
}
}
}
注意:这里有几个错误的地方
第一个就是合并的时候,我要判断a与b的祖先是不是一样。如果是一样的,那么节点数量没有必要增加
第二个就是不相等的时候,如果我没有提前保留不相等的a,b的祖先,并且我在合并之后才做数量统计就是错误的,就相当于我自身增加。
题目
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber
class Solution {
public:
int rob(vector& nums) {
if(nums.empty())//如果是空的就代表我没有必要进行判断
{
return 0;
}
if(nums.size()==1)
return nums[0];
else
if(nums.size()==2)
return max(nums[0],nums[1]);//在第一个房子和第二个房子选择利益最大化
int n=nums.size();
int dp[210];
memset(dp,0,sizeof(dp));
dp[0]=nums[0];
dp[1]=max(nums[1],nums[0]);
for(int i=2;i
未完成:
dp 5道题目
八皇后
字符串哈希表
3个图论最短路径
如果今天完成了的话,还会后续更新。
以后会继续连更,请各位见证我的成长吧。
我很菜,但是我会努力的