zoukankan      html  css  js  c++  java
  • FZU 2087 统计树边

    Problem 2087 统计树边
    Accept: 197 Submit: 571
    Time Limit: 1000 mSec Memory Limit : 32768 KB

    Problem Description

    在图论中,树:任意两个顶点间有且只有一条路径的图。

    生成树:包含了图中所有顶点的一种树。

    最小生成树:对于连通的带权图(连通网)G,其生成树也是带权的。生成树T各边的权值总和称为该树的权,权最小的生成树称为G的最小生成树(Minimum Spanning Tree)。最小生成树可简记为MST。

    但是,对于一个图而言,最小生成树并不是唯一的。

    现在,给你一个连通的有权无向图,图中不包含有自环和重边,你的任务就是寻找出有多少条边,它至少在一个最小生成树里。图保证连通。

    Input

    输入数据第一行包含一个整数T,表示测试数据的组数。对于每组测试数据:

    第一行包含两个整数n,m(1

    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    #include <algorithm>
    #include <stdio.h>
    
    using namespace std;
    #define MAX 100000
    struct Node
    {
        int x;
        int y;
        int w;
    }a[MAX+5];
    int father[MAX+5];
    int n,m;
    int find(int x)
    {
        if(x!=father[x])
            father[x]=find(father[x]);
        return father[x];
    }
    int cmp(Node a,Node b)
    {
        return a.w<b.w;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        int x,y,z;
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&x,&y,&z);
                a[i].x=x;
                a[i].y=y;
                a[i].w=z;
            }
            sort(a,a+m,cmp);
            for(int i=1;i<=n;i++)
                father[i]=i;
            int ans=0;
            int i=0;
            while(i<m)
            {
                int j=i;
                while(a[j].w==a[j+1].w)
                {
                    int xx=find(a[j].x);
                    int yy=find(a[j].y);
                    if(xx!=yy)
                        ans++;
                    j++;
                }
                int xx=find(a[j].x);
                int yy=find(a[j].y);
                if(xx!=yy)
                    ans++;
                j=i;
                while(a[j].w==a[j+1].w)
                {
                    int xx=find(a[j].x);
                    int yy=find(a[j].y);
                    if(xx!=yy)
                        father[xx]=yy;
                    j++;
                }
                xx=find(a[j].x);
                yy=find(a[j].y);
                if(xx!=yy)
                    father[xx]=yy;
                i=j+1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    算法53----换钱的最小次数和方法数【动态规划】
    算法52-----矩阵最小路径【动态规划】
    Data
    Git
    Git
    Git
    Git
    DevOps
    Docker
    Tools
  • 原文地址:https://www.cnblogs.com/dacc123/p/8228789.html
Copyright © 2011-2022 走看看