GoldMoon

记录成长点滴

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

题目貌似出的有点问题,考试的时候理解有点偏差。题干里说的是无向边,然而样例里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;
}


阅读更多
版权声明:本文为博主原创文章,转载请注明出处。若博文中有引用侵权,请告知博主。 https://blog.csdn.net/moringrain/article/details/46802775
文章标签: acm hdoj kruskal
个人分类: ACM
上一篇TJU4111-Binomial efficient(数论)
下一篇TJU-4113- Determine X(数学题)
想对作者说点什么? 我来说一句

happy tree friends

2010年05月09日 3.66MB 下载

没有更多推荐了,返回首页

关闭
关闭