P2820 局域网
题目背景
某个局域网内有 n n n 台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象。因为连接计算机的网线本身不同,所以有一些连线不是很畅通,我们用 f ( i , j ) f(i,j) f(i,j) 表示 i , j i,j i,j 之间连接的畅通程度, f ( i , j ) f(i,j) f(i,j) 值越小表示 i , j i,j i,j 之间连接越通畅, f ( i , j ) f(i,j) f(i,j) 为 0 0 0 表示 i , j i,j i,j 之间无网线连接。
题目描述
现在需要解决回路问题,我们将除去一些连线,使得网络中没有回路,不改变原图节点的连通性,并且被除去网线的 ∑ f ( i , j ) \sum f(i,j) ∑f(i,j) 最大,请求出这个最大值。
输入格式
第一行两个正整数 n , k n,k n,k。
接下来的 k k k 行每行三个正整数 i , j , m i,j,m i,j,m 表示 i , j i,j i,j 两台计算机之间有网线联通,通畅程度为 m m m。
输出格式
一个正整数, ∑ f ( i , j ) \sum f(i,j) ∑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 ≤ n ≤ 100 1\le n \le 100 1≤n≤100, 1 ≤ f ( i , j ) ≤ 1000 1\le f(i,j)\le 1000 1≤f(i,j)≤1000。
C++实现
#include<iostream>
#include<cstdio>
#include<algorithm>//sort所需要的STL头文件
using namespace std;
int n,m,f[200],ans,x,sum;
struct lol{
int from,to,val;//使用结构体存储边的两端点,长度
}l[20010];
bool cmp(lol a, lol b){
return a.val<b.val;//sort排序设置边长为关键字
}
int find(int x){
if (f[x]==x) return x;
else return f[x]=find(f[x]);//并查集
}
void Kuskal(){
int a,b;
sort(l+1,l+1+m,cmp);//sort快排
for (int i=1; i<=m; i++){
a=find(l[i].from); b=find(l[i].to);//找两点的祖先
if (a==b) continue;//ab在同一集合,即a,b点已连通,则跳过
sum+=l[i].val;//记录长度
f[a]=b;//合并
x++;
if (x==n) return;//边达到需要值,跳出函数
}
}
int main(){
int i;
cin>>n>>m;
for (i=1; i<=n; i++){
f[i]=i;
}
for (i=1; i<=m; i++){
scanf("%d%d%d",&l[i].from,&l[i].to,&l[i].val);
ans+=l[i].val;//算总长
}
Kuskal();
printf("%d",ans-sum);//输出
return 0;
}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容