[并查集]修复公路

传送门

思考过程

这个数据范围好大啊,我想省点空间于是就想到了vector,思路很简单,就是先根据建造时间排个序,然后从小到大的顺序合并,合并一次检查一次,如果最后祖先都一样那么就是通了。

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
int fa[100010];
int n,m;
struct node
{
    int x,y,z;
};
vector<node> v;
vector<node>::iterator it;
bool cmp(const node &a,const node &b){return a.z < b.z;}
int find(int pos)
{
    if(fa[pos] == pos) return pos;
    return fa[pos] = find(fa[pos]);
}
bool search()
{
    int pre = fa[1];
    register int i;
    for(i=1;i<=n;i++)
    {
        if(fa[i] != pre)
        {
            return 0;
        }
    }
    return 1;
}
int main()
{
    register int i;
    //freopen("1.in", "r", stdin);
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)fa[i] = i;
    for(i=1;i<=m;i++)        
    {
        int aa,bb,cc;
        scanf("%d%d%d",&aa,&bb,&cc);
        v.push_back(node {aa,bb,cc});
    }
    sort(v.begin(),v.end(),cmp);
    int ans = 0;
    for(it=v.begin();it!=v.end();it++)
    {
        int aa,bb,cc;
        aa = it->x;
        bb = it->y;
        cc = it->z;
        int x = find(aa);
        int y = find(bb);
        if(x != y)
        {
            ans = cc;
            //printf("add : %d\n",cc);
            fa[bb] = aa;
        }
        if(search())
        {
            printf("%d",ans);
            return 0;
        }
        //printf("%d\n",cc);
        //printf("%d %d %d\n",*(it));
    }
    printf("-1");
    return 0;
}

结果:
在这里插入图片描述
这组数据其实在第四次的时候就已经通了,但是我的fa记录有问题,我以为让村子号小的放在前面就可以解决问题。但又发现

在这里插入图片描述

最终思路

用个鸡儿的STL,寻常并查集即可,每次联通一条路的时候就n–

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct hh
{
	int x,y,t;
}a[200000];
int f[200000],n,m;
int cmp(const hh &a,const hh &b){return a.t<b.t;}
int find(int x){return f[x]==x?x:(f[x]=find(f[x]));}//极致压缩
int main()
{
	1s41canf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].t);
	sort(a+1,a+m+1,cmp);
	for(int i=1;i<=n;i++)f[i]=i;
	for(int i=1;i<=m;i++)
	{
		int fx=find(a[i].x),fy=find(a[i].y);
		if(fx!=fy)f[fx]=fy,n--;
		if(n==1){cout<<a[i].t;return 0;}
	}
	cout<<-1<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章