C++中左移<<和右移>>的使用

在C++中,经常会看到别人有int ans=1<<30;类似的代码。经查阅,<<是位运算符号,代表把1的二进制表示左移30位,左移一位(即在原来的数后面加一个0)相当于乘以2,左移30位应该是相当于乘以2的30次方。可以写几句简单的代码做一下验证,例如1<<4应该得到16,代码如下

#include<iostream>
using namespace std;
int main()
{
  int a = 1 << 4;
  cout << a << endl;
  return 0;
}

同理,也有右移运算,又移一位相当于除2

#include<iostream>
using namespace std;
int main()
{
	int a = 4 >>1;
	cout << a << endl;
	return 0;

输出结果应该是2.

这也是一个最小生成树的问题,同样可以使用Kruskal算法或Prim算法求解。以下是Kruskal算法的另一种实现,使用数组模拟并查集: ```c++ #include <iostream> #include <algorithm> using namespace std; const int N = 35, M = 1010; struct Edge { int u, v, w; } edges[M]; bool cmp(const Edge& a, const Edge& b) { return a.w < b.w; } int parent[N]; int find(int x) { if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } void unite(int x, int y) { int px = find(x), py = find(y); if (px != py) { parent[px] = py; } } int kruskal(int n, int m) { for (int i = 1; i <= n; i++) { parent[i] = i; } sort(edges, edges + m, cmp); int cnt = 0, ans = 0; for (int i = 0; i < m; i++) { int u = edges[i].u, v = edges[i].v, w = edges[i].w; if (find(u) == find(v)) { continue; } unite(u, v); ans += w; cnt++; if (cnt == n - 1) { break; } } if (cnt < n - 1) { return -1; } else { return ans; } } int main() { int n, m; cin >> n >> m; for (int i = 0; i < m; i++) { cin >> edges[i].u >> edges[i].v >> edges[i].w; } int ans = kruskal(n, m); if (ans == -1) { cout << "Fail" << endl; } else { cout << ans << endl; } return 0; } ``` 在这个实现,我们使用了两个数组:parent和edges。其parent数组用于模拟并查集,edges数组用于存储所有的边。在kruskal函数,我们首先初始化每个节点的父节点为自己,然后将所有边按权值从小到大排序。接着从小到大枚举每条边,如果它的两个端点不在同一个连通块内,则将它们合并,并将边的权值累加到答案。最后如果生成树的边数小于n-1,则说明无法将所有节点连通,打印“Fail”,否则打印答案。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值