POJ1258 Agri-Net

学并查集的时候写的。将所有距离储存在结构体中,然后按距离从小到大排序,遍历,如果a和b不在一个集合中,把这个距离加到答案上,然后把a和b所在的集合合并。

当然,时间复杂度是N的平方,幸好N不是很大。(其实也可以优化,我懒得去写而已)。不过好像别人都是用prim和kruskal写的。(告诉你们吧,我还没学)

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int fa[101],n;
struct node
{
    int a,b,num;
}p[10001];
int find_(int a)
{
    if(a!=fa[a])
        fa[a]=find_(fa[a]);
    return fa[a];
}
void union_(int a,int b)
{
    int pa=find_(a);
    int pb=find_(b);
    if(pa==pb)
        return ;
    fa[pb]=pa;
}
int cmp1(node a,node b)
{
    return a.num<b.num;
}
int main()
{
    int i,j,ans,js;
    while(scanf("%d",&n)!=EOF)
    {
        ans=js=0;
        for(i=1;i<=n;i++)
            fa[i]=i;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%d",&p[++js].num);
                p[js].a=i,p[js].b=j;
            }
        }
        sort(p+1,p+js+1,cmp1);
        for(i=1;i<=js;i++)
        {
            if(find_(p[i].a)!=find_(p[i].b))
            {
                ans+=p[i].num;
                union_(p[i].a,p[i].b);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值