添加冗余链路可以提高以太网的可靠性,但是容易形成网络环路,造成广播风暴、交换机的帧交换表振荡等问题。
以太网交换机使用生成树协议STP(Spanning Tree Protocol),可以增加冗余链路来提高网络可靠性的同时又避免网络环路带来的各种问题。
生成树协议STP作用:
(1)不论交换机之间采用怎样的物理连接,交换机都能够自动计算并构建一个逻辑上没有环路的网络,其逻辑拓扑结构必须是树形的(无逻辑环路);
(2)最终生成的树形逻辑拓扑确保连通整个网络;
(3)当首次链接交换机或网络物理拓扑发生变化时,交换机都将进行生成树的重新计算。
克鲁斯卡尔算法(Kruskal Algorithm)
时间复杂度:O(mlog(m))
(1)将所有边按照权重从小到大排序 O(mlog(m));
(2)枚举每条边(a, b,权重c),如果新加入的点没有形成环路,则将此点加入到集合中;
(3)使用并查集。
C++代码实现:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010, M = 200010,INF = 0x3f3f3f3f;
int n,m;
int p[N];
struct Edge
{
int a,b,w;
bool operator< (const Edge &W)const
{
return w < W.w;
}
}edges[M];
int find(int x)
{
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
int kruskal()
{
sort(edges,edges+m);//将边的权重按照大小一一排序
for(int i = 1; i <= n; i ++) p[i] = i;//初始化并查集
int res = 0, cnt = 0;//res记录最小生成树的树边权重之和,cnt记录的是全部加入到树的集合中边的数量(可能有多个集合)
for(int i = 0; i < m; i ++)
{
int a = edges[i].a,b = edges[i].b,w = edges[i].w;
a = find(a), b = find(b);
if(a != b)
{
/*
具体可以参考连通块中点的数量,如果a和b已经在一个集合当中了,说明这两个点已经被一种方式连接起来了,
如果加入a-b这条边,会导致集合中有环的生成,而树中不允许有环生成,所以一个连通块中的点的数量假设
为x,那么里面x个节点应该是被串联起来的,有x-1条边,所以只有当a,b所属的集合不同时,才能将a-b这条
边加入到总集合当中去
*/
p[a] = b;//将a,b所在的两个集合连接起来
res += w;//加入到集合中的边的权重之和
cnt ++;//因为加入的是a-b的这一条边,将a,b所在的两个集合连接之后,全部集合中的边数加1
}
}
if(cnt < n - 1) return INF;//不可以生成最小生成树
return res;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 0; i < m; i ++)
{
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
edges[i] = {a,b,w};
}
int t = kruskal();
if(t == INF) puts("impossible");
else printf("%d\n",t);
return 0;
}