TJU-4117 Happy tree friends(最小生成树)

本文详细解析了一道算法题中关于最小生成树与无向边概念的理解误区,提供了正确的解题思路及kruskal算法的应用。通过实际样例对比,帮助读者准确把握算法核心,避免常见误解。

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

题目貌似出的有点问题,考试的时候理解有点偏差。题干里说的是无向边,然而样例里Wij != Wji。晕了。以为是最小树形图。

最后和AC同学打听了一下,直接按无向边做就好了,其余的不用管。还有一定要加的那个边的方向不要边。

剩下就是标准的kruskal算法了。先把边按升序排序,再利用并查集向一个集合里加。如果没有冲突(要加的边的两点还没有再一个集合里,那么把这条边的两点相连,权值加入答案)。处理必须要加入的边,先把它的权值加入答案,再把这条边的权值修改为0,排序后,这条边一定会被选中。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=10010;

int n,m,f[N];
struct edge
{
    int x,y;
    int w;
}e[N];

bool cmp(const edge a,const edge b)
{
    return a.w<b.w;
}

int root(int x)
{
    if(f[x]==x) return x;
    f[x]=root(f[x]);
    return f[x];
}

void work()
{
    int i,j,k,t,sum,ans;
    int u,v;

    sum=0;
    m=0;
    memset(e,0,sizeof(e));
    for(i=0;i<=n;i++) f[i]=i;

    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        {
            scanf("%d",&e[m].w);
            e[m].x=i;
            e[m].y=j;
            if(i==j) e[m].w=100000000;
            m++;
        }
    scanf("%d%d",&u,&v);
    sum=e[(u-1)*n+v-1].w;
    e[(u-1)*n+v-1].w=0;
    sort(e,e+m,cmp);
    for(i=0;i<m;i++)
    {
        j=root(e[i].x);
        k=root(e[i].y);
        if(j!=k)
        {
            f[j]=k;
            sum+=e[i].w;
        }
    }

    printf("%d\n",sum);
}

int main()
{
    while(scanf("%d",&n)!=EOF)
        work();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值