SDUT 周赛 2494 Minimum Spanning Tree? 最小生成树变形

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2494

题意:
给你一个图,该图可能存在很多最小生成树。求最小生成树可能包含的边的个数。

思路:
这里我们将权值相同的边看成一个块,按块来处理。按krusal的算法处理,检查每一块当该边加入后最小生成树后不会形成环就+1,这里我们先不把他们加入,检查完后再将边加入,这样就能保证可能加入最小生成树的相同的权值的边都加入了,并且我们也计数了。

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <queue>

#include <stack>

#include <set>

#include <map>

#include <string>



#define CL(a,num) memset((a),(num),sizeof(a))

#define iabs(x)  ((x) > 0 ? (x) : -(x))

#define Min(a,b) (a) > (b)? (b):(a)

#define Max(a,b) (a) > (b)? (a):(b)



#define ll long long

#define inf 0x7f7f7f7f

#define MOD 1073741824

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("<------------------->")

#define maxn 100007

#define M 500007

#define N 100007

using namespace std;

//freopen("din.txt","r",stdin);



struct node

{

    int u,v,w;

}g[M];

int f[N];

int n,m;



int cmp(node a,node b)

{

    return a.w < b.w;

}

int find(int x)

{

    if (x != f[x])

    f[x] = find(f[x]);

    return f[x];

}

void Kruscal()

{

    int i,j;

    int ans = 0;

    for (i = 1; i <= n; ++i) f[i] = i;

    sort(g,g + m,cmp);

    for (i = 0; i < m; i = j)

    {

        for (j = i; j < m; ++j)

        {

            if (g[j].w != g[i].w) break;

            if (find(g[j].u) != find(g[j].v))

            ans++;

        }

        for (int k = i; k < j; ++k)

        {

             f[find(g[k].u)] = find(g[k].v);

        }

    }

    printf("%d\n",ans);

}

int main()

{

    //freopen("din.txt","r",stdin);

    int i,j;

    while (~scanf("%d%d",&n,&m))

    {

        for (i = 0; i < m; ++i)

        {

            scanf("%d%d%d",&g[i].u,&g[i].v,&g[i].w);

        }

        Kruscal();

    }

}

  

你可能感兴趣的:(最小生成树)