SSL2817 2017年11月1日提高组 树论(并查集)

来源:互联网 发布:新网域名查询 编辑:程序博客网 时间:2024/04/20 01:19

2017年11月1日提高组 树论

Description

这里写图片描述

Input

这里写图片描述

Sample Input

1
4 2
3 1 3375
3 2 8707
5 5
2 1 455
3 1 3616
4 1 9494
5 4 1448
5 1 8366
Sample Output

-1
7911
Hint
这里写图片描述

分析:按边权从小到大排序,枚举最小边,往后把边加入并查集,如果n个点都属于同一集合时就统计答案

代码

#include <cstdio>#include <algorithm>#define N 5000using namespace std;struct arr{    int x,y,w;}a[N];int f[N],n,m;int find(int x){    if (f[x]==x) return x;    return f[x]=find(f[x]);}int min(int x,int y){    return x<y?x:y;}int so(arr p,arr q){    return p.w<q.w;}int main(){//  freopen("graph.in","r",stdin);//  freopen("graph.out","w",stdout);    int T;    scanf("%d",&T);    while (T--)    {        scanf("%d%d",&n,&m);        for (int i=1;i<=m;i++)            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);        sort(a+1,a+m+1,so);        int ans=123456789;        for (int i=1;i<=m;i++)        {            int tot=0;            for (int j=1;j<=n;j++)                f[j]=j;            int j=i;            while (j<=m)            {                int u=find(a[j].x);                int v=find(a[j].y);                if (u!=v)                {                    tot++;                    f[u]=v;                    if (tot==n-1) break;                }                j++;            }            if (tot==n-1) ans=min(ans,a[j].w-a[i].w);        }        if (ans==123456789) ans=-1;        printf("%d\n",ans);    }    fclose(stdin);    fclose(stdout);}
阅读全文
0 0