求连通分支的数目
逆向思维:首先按时间对桥梁排序,然后从最后的一座桥开始枚举,要是跟上一一座桥不在同一时间,而且他让两座岛屿产生的新的联系ans加一
(等价于正向的时候把时间相同的桥删除,判断是否让某些岛屿孤立)。
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,a,b,ans=0,lastday=-1;
int pre[10010];
struct node {
int x,y,day;
} e[100010];
bool cmp (node a,node b) {
return a.day>b.day;
}
int find(int x) {
/*int r=x;
while (pre[r]!=r) r=pre[r];
return r;*/
return pre[x]==x?x:pre[x]=find(pre[x]); //不这样写会超时
}
bool vis(int x,int y) {
a=find(x);
b=find(y);
if (a==b) return false;
pre[b]=a;
return true;
}
int main()
{
scanf ("%d%d",&n,&m);
for (int i=0;i<m;i++)
scanf ("%d%d%d",&e[i].x,&e[i].y,&e[i].day);
sort(e,e+m,cmp);
for (int i=1;i<=n;i++) pre[i]=i;
for (int i=0;i<m;i++) {
if (vis(e[i].x,e[i].y) && e[i].day!=lastday) { 两个小岛不连通,且与上一个大桥的天数不同
ans++;
lastday=e[i].day;
}
}
printf ("%d\n",ans);
return 0;
}