fzu 2087并查集的运用求最小生成树的等效边

来源:互联网 发布:女生电脑包 知乎 编辑:程序博客网 时间:2024/05/16 12:49
//对数组排序后,对于边相同并且边的两端不在一个集合内的一定是等效边或者必加边,
//第一数数,第二合并集合
#include<stdio.h>#include<stdlib.h>#define N 110000int pre[N];struct node {int x,y,w;}ma[N];int findd(int x) {if(x!=pre[x])    pre[x]=findd(pre[x]);return pre[x];}int cmp(const void *a,const void*b) {return (*(struct node *)a).w-(*(struct node *)b).w;}int main() {    int n,m,i,j,k,cou,t,a,b,c;     scanf("%d",&t);     while(t--) {        scanf("%d%d",&n,&m);        for(i=1;i<=n;i++)            pre[i]=i;        for(i=0;i<m;i++)            scanf("%d%d%d",&ma[i].x,&ma[i].y,&ma[i].w);        qsort(ma,m,sizeof(ma[0]),cmp);        cou=0;        c=0;k=0;j=0;        for(i=0;i<m&&k<n-1;) {            while(ma[c].w==ma[j].w) {            a=findd(ma[j].x);            b=findd(ma[j].y);            if(a!=b)                cou++;            j++;                }                j=i;           while(ma[c].w==ma[j].w) {            a=findd(ma[j].x);            b=findd(ma[j].y);            if(a!=b) {                pre[b]=a;                k++;            }            j++;           }           c=j;           i=j;        }         printf("%d\n",cou);     }return 0;}
0 0