sdut 2494 Minimum Spanning Tree?

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

按求最小生成树的步骤 先按边的长度进行排序

我们把每一个边权相等的一个段看做一个单位

那我们一个单位一个单位的求

假如求到第k个单位了 无论前面k-1个单位怎么取舍 结果都是前面出现的所有端点都在一个联通块里面

无论度第k个单位怎么取舍前k个单位出现的端点也都在一个联通块里(求第k+1个联通块时)

所有按照排好的顺序 每个单位是相互独立的

对一到了第k个单位时  先把这个单位的所有边先搜一遍 如果哪个边的两个端点不在一个联通块内 则说明它是有资格成为某个最小生成树中的一员

所有计数 但不做其他操作

然后再搜一遍 把所以端点都联通

最后计数结果就是答案

代码:

#include<iostream>

#include<stdio.h>

#include<string.h>

#include<math.h>

#include<algorithm>

#include<vector>

#include<set>

#include<map>

#include<string>

#include<queue>

#include<stack>

#include <iomanip>

using namespace std;

#define LL long long

const int INF=0x3f3f3f3f;

//priority_queue<int,vector<int>,greater<int> >qt;

const int N=100005;

const int M=1000005;

int f[N];

struct node

{

    int l,r,k;

}mem[M];

bool cmp(node x,node y)

{

    return x.k<y.k;

}

int findx(int x)

{

    if(f[x]!=x)

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

    return f[x];

}

int main()

{

    //freopen("data.in","r",stdin);

    int n,m;

    while(cin>>n>>m)

    {

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

        cin>>mem[i].l>>mem[i].r>>mem[i].k;

        sort(mem,mem+m,cmp);

        for(int i=1;i<=n;++i)

        f[i]=i;

        int sum=0;

        int I;

        for(int i=0;i<m;i=I)

        {

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

            {

                if(mem[I].k!=mem[i].k)

                break;

                if(findx(mem[I].l)!=findx(mem[I].r))

                ++sum;

            }

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

            {

                f[findx(mem[j].l)]=findx(mem[j].r);

            }

        }

        cout<<sum<<endl;

    }

    return 0;

}

  

 

你可能感兴趣的:(tree)