P2820 局域网

文章讲述了如何解决局域网中的回路问题,使用Kruskal算法结合并查集来消除回路,同时最大化网络中去除的边的畅通程度之和。算法首先按边的畅通程度排序,然后尝试连接未连接的节点,直到所有节点连通,输出最大畅通程度之和。
摘要由CSDN通过智能技术生成

# 局域网

## 题目背景

某个局域网内有 $n$ 台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象。因为连接计算机的网线本身不同,所以有一些连线不是很畅通,我们用 $f(i,j)$ 表示 $i,j$ 之间连接的畅通程度,$f(i,j)$ 值越小表示 $i,j$ 之间连接越通畅,$f(i,j)$ 为 $0$ 表示 $i,j$ 之间无网线连接。

## 题目描述

现在需要解决回路问题,我们将除去一些连线,使得网络中没有回路,**不改变原图节点的连通性**,并且被除去网线的 $\sum f(i,j)$ 最大,请求出这个最大值。

## 输入格式

第一行两个正整数 $n,k$。

接下来的 $k$ 行每行三个正整数 $i,j,m$ 表示 $i,j$ 两台计算机之间有网线联通,通畅程度为 $m$。

## 输出格式

一个正整数, $\sum f(i,j)$ 的最大值。

## 样例 #1

### 样例输入 #1

```
5 5
1 2 8
1 3 1
1 5 3
2 4 5
3 4 2

```

### 样例输出 #1

```
8
```

## 提示

对于全部数据,保证 $1\le n \le 100$,$1\le f(i,j)\le 1000$。

主要算法:Kluskal

介绍一下:主要用到了并查集,将所有的边的畅通程度程度从小到大排序。Kuskal的思路就是一共有n个点,用n-1条边就可以将这n个点连起来。所以用并查集将没连起来的畅通程度最小的两个点连起来,每连一条就+1。一但加到总点数-1条就可以退出。

另外,将所有畅通程度加起来,把n-1条去掉,就是最大的畅通程度。

AC代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
	int a,b,w;
}Edge[500005];//边集数组 
int n,m;
int fa[500005]; //并查集 
bool cmp(node a,node b){//重载比较函数 
	return a.w<b.w;
}
int find(int x){//并查集找祖宗 
	if(fa[x]!=x)fa[x]=find(fa[x]);
	return fa[x];
} 
int main(){
	int cnt=0;
	cin>>n>>m;
	for(int i=1;i<=n;i++)fa[i]=i;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		Edge[i].a=x;
		Edge[i].b=y;
		Edge[i].w=z;
		cnt+=z;
	}
	sort(Edge+1,Edge+1+m,cmp);
	int res=0;
	for(int i=1;i<=m;i++){
		if(find(Edge[i].a)!=find(Edge[i].b)){
			fa[find(Edge[i].a)]=find(Edge[i].b);
			res+=Edge[i].w;
		}
	}
	cout<<cnt-res;
	
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值