思维 并查集基本功

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+9;
int fa[N];

struct node{
    int a,b,c;
}t[N];

//查找
int find(int x) {
    if( x==fa[x] ) return fa[x];
    else {
        fa[x]=find(fa[x]);
        return fa[x];
    }
}
//合并
void merge(int a,int b){
    int a_fa=find(a),b_fa=find(b);
    if( a_fa != b_fa )
        fa[a_fa]=b_fa;//b的祖先成为了a祖先的祖先,a家合并到b家
}

int main()
{
    int n;cin>>n;
    
    for(int i=0;i<n;i++) fa[i]=i;//初始化
    
    for(int i=1 ;i<=n;i++) {
        int a,b,c; cin>>a>>b>>c;
        merge(a,i);    //a和i交上了朋友
        t[i]={a,b,c}; //暂且i家族的人员和礼物是a和b c
    }
    
    vector<int> arr[N];//第一维是几个祖宗
    for(int i=1;i<=n;i++) {//注意先合并人,再合并价格
        arr[find(i)].push_back(t[i].b);//第二维是所有价格都包含进去
        arr[find(i)].push_back(t[i].c);
    }
    
    int ans=-0x3f3f3f3f;//一个无穷小的数
    for(auto it:arr ) {//it代表arr[i] i++
        if( it.size()==0 ) continue;
        
        vertor<int> v=it; sort( v.begin(),v.end() );//第二维的价格进行排序
        
        int mi,ma,cn=0;
        for(auto j:v){//j代表第二维价格int
            cn++;
            if(cn==1) mi=j;//排完序后,第一个是最小的,最后一个是最大的
            if( cn==v.size() ) mx=j;
        }
        
        ans=max(ans,mx-mi);//每一个祖宗arr[i]都有一个插值,每次计算完插值比较一下
    }
    cout<<ans<<"\n";
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值