FZU 2087 统计树边

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2087


题意:给出一个有n个点m条边的图,没有重边和自环,问有多少条边可以是最少生成树上的边


思路:对Kruscal不熟悉……没有想出来,图上只有2种边,一种是最少生成树上的边,一种不是最少生成树上的边,每次贪心的时候有权值相同且不在同一个集合的边res++,之后将这些边全放进生成树的集合里,最终得到的答案就是所求



#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 100030
using namespace std;

struct edge
{
    int x,y,w;
    edge(int x=0,int y=0,int w=0):x(x),y(y),w(w){}
}e[maxn];

int fa[maxn];
int n,m;

bool cmp(edge p,edge q)
{
    return p.w<q.w;
}


int finds(int x)
{
    if (x==fa[x]) return x;
    else return fa[x]=finds(fa[x]);
}

int Kruscal()
{

    sort(e+1,e+m+1,cmp);
    int cnt=n;
    int res=0;
    for (int i=0;i<=n;i++)
        fa[i]=i;
    for (int i=1;i<=m;i++)
    {
        int pos=i;
        while (e[i].w==e[pos].w)
        {
            int t1=finds(e[pos].x);
            int t2=finds(e[pos].y);
            if (t1!=t2)
                res++;
            pos++;
        }

        pos=i;
        while (e[i].w==e[pos].w)
        {
            int t1=finds(e[pos].x);
            int t2=finds(e[pos].y);
            if (t1!=t2)
                fa[t1]=t2;
            pos++;
        }
    }
    return res;
}

int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
        }
        int res=Kruscal();
        printf("%d\n",res);
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值