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

最后都变了- 提交于 2020-02-28 04:52:09

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();
    }
}

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!