国王的烦恼(并查集)

题目描述

C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了m座大桥,每座大桥连接两座小岛。两个小岛间可能存在多座桥连接。然而,由于海水冲刷,有一些大桥面临着不能使用的危险。 

如果两个小岛间的所有大桥都不能使用,则这两座小岛就不能直接到达了。然而,只要这两座小岛的居民能通过其他的桥或者其他的小岛互相到达,他们就会安然无事。但是,如果前一天两个小岛之间还有方法可以到达,后一天却不能到达了,居民们就会一起抗议。 

现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。现在他想知道居民们会有多少天进行抗议。

 

输入

输入的第一行包含两个整数n,  m,分别表示小岛的个数和桥的数量。 
接下来m行,每行三个整数a,  b,  t,分别表示该座桥连接a号和b号两个小岛,能使用t天。小岛的编号从1开始递增。 

 

输出

输出一个整数,表示居民们会抗议的天数。 

 

样例输入

4 4
1 2 2
1 3 2
2 3 1
3 4 3

 

样例输出

2

 

提示

样例说明: 
      第一天后2和3之间的桥不能使用,不影响。 
      第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。 
      第三天后3和4之间的桥不能使用,居民们会抗议。 
数据规模和约定:
      对于30%的数据,1<=n<=20,1<=m<=100; 
      对于50%的数据,1<=n<=500,1<=m<=10000; 
      对于100%的数据,1<=n<=10000,1<=m<=100000,1<=a, b<=n,1<=t<=100000。

解题思路:

居民会在两个小岛不能到达之后抗议一天,而同一天中可能会有多个小岛不能到达,所以在判断两个小岛是否能到达时还应该判断两个小岛不能到达的时间是不是同一天。

#include <stdio.h>
#include <algorithm>
using namespace std;
#define N 10020
int f[N];
struct data{
    int u;
    int v;
    int w;
}e[N*10];
int cmp(data a, data b)
{
    return a.w>b.w;
}
int getf(int v)
{
    if(f[v]==v)
        return v;
    else
    {
        f[v]=getf(f[v]);
            return f[v];    
    }   
} 
int merge(int u, int v)
{
    int t1, t2;
    t1=getf(u);
    t2=getf(v);
    if(t1!=t2)
    {
        f[t2]=t1;
        return 1;
    }
    return 0;
}
int main()
{
    int i, n, m, a, b, t, ans, w;
    while(scanf("%d%d", &n, &m)!=EOF)
    {
    	ans=0;
        for(i=0; i<m; i++)
            scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
        sort(e, e+m, cmp);
        for(i=1; i<=n; i++)
            f[i]=i;
        w = e[0].w+1;
        for(i=0; i<m; i++)
        {
            if(merge(e[i].u, e[i].v) && w!=e[i].w)
            {
            	ans++;
            	w=e[i].w;
			}  
        }
        printf("%d\n", ans);
    }
    return 0;
}

 

posted @ 2019-05-28 17:17  宿星  阅读(107)  评论(0编辑  收藏  举报