[並查集]修復公路

傳送門

思考過程

這個數據範圍好大啊,我想省點空間於是就想到了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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章