2022/2/15总结

本文探讨了最小生成树问题的实现,通过比较两个不同场景(无线通讯网络节省边长策略和地毯拆分)中使用最小生成树算法的方法。首先介绍了如何利用并查集和边的权重从小到大排序找到无环路径,然后展示了如何在无线通讯网络中通过合并卫星节点来优化网络结构。最后,通过大到小排序拆分地毯,展示了算法在实际问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.最小生成树

将所有的边从小到大排序,再用并查集查看是否有环

#include <iostream>
#include <algorithm>
using namespace std;
struct  node
{
   int x,y,z;
}edge[501000];
int fa[501000];
int sum=0;
bool cmp(node a,node b)
{
    return a.z<b.z;
}
int get(int x)
{
    return x==fa[x]?x:fa[x]=get(fa[x]);
}
int main()
{
 int n,m;
 cin >> n >> m;
for(int i=1;i<=m;i++)
{
   cin >> edge[i].x >> edge[i].y >> edge[i].z;

}
for(int i=0;i<=n;i++)
fa[i]=i;
sort(edge+1,edge+m+1,cmp);
for(int i=1;i<=m;i++)
{
    int x=get(edge[i].x);
    int y=get(edge[i].y);
    if(x==y)continue;
    fa[y]=x;
    sum+=edge[i].z;
}
int ans=0;
for(int i=1;i<=n;i++)
if(i==fa[i])ans++;
if(ans>1)cout << "orz";
else cout << sum;
}

2.无线通讯网

一个卫星节点可节约一条边,我们节约较大的边,即找边时减去

#include <bits/stdc++.h>
using namespace std;
struct  node
{
    double z, x,y;
  
}edge[501000];
int fa[501000];
int a[501000];
int b[501000];
double sum=0;
bool cmp(node a,node b)
{
    return a.z<b.z;
}
int find(int x)
{
    if(x!=fa[x])
    {
        fa[x]=find(fa[x]);

    }
    return fa[x];
}
void unity(int x, int y)
{
    int r1=find(x);
    int r2=find(y);
    fa[r1]=r2;
}
int main()
{
 int n,m;
 cin >> n >> m;
 int p=0;
for(int i=1;i<=m;i++)
{
 
   cin >> a[i] >> b[i];
   for(int j=1;j<i;j++)
   {
       p++;
       edge[p].x=i;
       edge[p].y=j;
       edge[p].z=sqrt((a[i] - a[j]) * (a[i] - a[j]) + (b[i] - b[j]) * (b[i] - b[j]));
   }


}
for(int i=1;i<=m;i++)
fa[i]=i;
sort(edge+1,edge+p+1,cmp);
int k=0;
for(int i=1;i<=p;i++)
{
    if(find(edge[i].x)!=find(edge[i].y))
    {
        unity(edge[i].x,edge[i].y);
        sum=edge[i].z;
        k++;
         if(k>=m-n)
    {
      printf("%.2lf",sum);
      return 0;
    }
    }
   
}


}

3.拆地毯

从大到小排序,利用模板

#include <iostream>
#include <algorithm>
using namespace std;
struct  node
{
   int x,y,z;
}edge[501000];
int fa[501000];
int sum=0;
bool cmp(node a,node b)
{
    return a.z>b.z;
}
int get(int x)
{
    return x==fa[x]?x:fa[x]=get(fa[x]);
}
int main()
{
 int n,m,k;
 cin >> n >> m>>k;
for(int i=1;i<=m;i++)
{
   cin >> edge[i].x >> edge[i].y >> edge[i].z;

}
for(int i=1;i<=n;i++)
fa[i]=i;
sort(edge+1,edge+m+1,cmp);
int s=0;
for(int i=1;i<=n;i++)
{
    int x=get(edge[i].x);
    int y=get(edge[i].y);
    if(x==y)continue;
    fa[y]=x;
     sum+=edge[i].z;
    s++;
if(s>=k)
{
    cout << sum;
    return 0;
}
    
   
    
}

 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值