每日编程中遇到任何疑问、意见、建议请公众号留言或直接撩Q474356284(备注每日编程)
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?
输入格式:
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
输出格式:
对每个测试用例,在1行里输出最少还需要建设的道路数目。
输入样例:
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0
输出样例:
1
0
2
998
解决方法:
(1)算法的基本思想:
并查集B站讲解:
https://www.bilibili.com/video/av38498175/?p=1
(2)代码实现:
#include <iostream>
#include <vector>
using namespace std;
//查找根节点
int find_root(int x, vector<int> &parent)
{
int x_root = x;
while (parent[x_root] != -1)
{
x_root = parent[x_root];
}
return x_root;
}
//合并结点
void union_vertices(int x, int y, vector<int> &parent, vector<int> &rank)
{
int x_root = find_root(x, parent);
int y_root = find_root(y, parent);
if (x_root == y_root)
{
;
}
else
{
//parent[x_root] = y_root;
if (rank[x_root] > rank[y_root])
{
parent[y_root] = x_root;
}
else if (rank[x_root] < rank[y_root])
{
parent[x_root] = y_root;
}
else
{
parent[x_root] = y_root;
rank[y_root]++;
}
}
}
int main()
{
int n, m;
while (~scanf("%d", &n) && n)
{
scanf("%d", &m);
int res = 0, x = 0, y = 0;
vector<int> parent(n + 1, -1);//根节点数组
vector<int> rank(n + 1, 0);//树的深度
for (int i = 0; i < m; i++)
{
cin >> x >> y;
union_vertices(x, y, parent, rank);
}
for (int j = 1; j <= n; j++)
{
if (j == find_root(j, parent))
res++;
}
printf("%d\n", res - 1);//还有res个独立的结点,仍需要res-1个路径
}
return 0;
}
在柠檬水摊上,每一杯柠檬水的售价为 5
美元。
顾客排队购买你的产品,(按账单 bills
支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5
美元、10
美元或 20
美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5
美元。
注意,一开始你手头没有任何零钱。
如果你能给每位顾客正确找零,返回 true
,否则返回 false
。
示例 1:
输入:[5,5,5,10,20]
输出:true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。
示例 2:
输入:[5,5,10]
输出:true
示例 3:
输入:[10,10]
输出:false
示例 4:
输入:[5,5,10,10,20]
输出:false
解释:
前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。
提示:
0 <= bills.length <= 10000
bills[i]
不是5
就是10
或是20
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
}
};