7.2寡人的难题

1329647-20181208132416023-168041755.png

最小生成树直接用kruskal就好了

#include<bits/stdc++.h>
#define sf scanf
#define scf(x) scanf("%d",&x)
#define scff(x,y) scanf("%d%d",&x,&y)
#define scfff(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define vi vector<long long>
#define mp make_pair
#define pf prlong longf
#define prf(x) printf("%d\n",x)
#define mm(x,b) memset((x),(b),sizeof(x))
#define rep(i,a,n) for (long long i=a;i<n;i++)
#define per(i,a,n) for (long long i=a;i>=n;i--)
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const double eps=1e-6;
const double pi=acos(-1.0);
const long long inf=0x7fffffff;    
const long long N=1e5+7;

struct Edge { 
    long long u, v, w; //边的顶点、权值
} edge[N*5]; //边的数组
long long pre[N];  //pre[i]为顶点 i 所在集合对应的树中的根结点
long long n, m;  //顶点个数、边的个数
long long Find( long long x ) 
{ //查找并返回节点 x 所属集合的根结点
    return pre[x]==x?x:pre[x]=Find(pre[x]);
}
bool cmp( Edge a, Edge b ) //实现从小到大排序的比较函数
{ 
    return a.w < b.w;
}
long long Kruskal( ) 
{
    for(int i=1;i<N;i++)pre[i]=i;
    sort(edge,edge+m,cmp);
    long long ans = 0;  //生成树的权值
    long long num = 0;  //已选用的边的数目
    long long u, v;  //选用边的两个顶点
    for(int i=0;i<m&&num<n-1;i++)
    {
        long long t1=Find(edge[i].u),t2=Find(edge[i].v);
        if( t1!=t2 ) 
        {
            //prlong longf( "%d %d %d\n", u, v, edge[i].w );
            ans += edge[i].w;
            num++;
            pre[t1]=t2;
            //pre[Find(t1)]=Find(t2);
        }
    }
    return ans;
}
int main( ) 
{
    long long u, v, w; //边的起点和终点及权值
    scff(n,m); //读入顶点个数 n
    rep(i,0,m)
        scfff(edge[i].u,edge[i].v,edge[i].w); 
    long long ans=Kruskal();
    cout<<ans;
    return 0;
}

转载于:https://www.cnblogs.com/wzl19981116/p/10087414.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值