图论练习1:银河英雄传说解题报告

感觉我写出来战争都结束了。。。。。。

题意

本题大概意思是不断的询问,合并并查集,如果询问的i,j在同一并查集内,打出它们中间有多少个数。

开始思路

开始连题目都看错了,以为只需要判断两个在不在同一并查集内就可以了(现在想想,蓝题怎么可能这么简单),所以十分尴尬的爆零,所以一定要细心啊

AC思路

这道题其实只需要定两个数组来存位置即可,一个为前(fq)数组,来存其到父亲中间有多少个数,一个存它后面有多少(合并时需要用到),这样我们把a的父亲的父亲的父亲的。。。前面都加起来,就可以求出它在并查集中的位置了,然后与b比较大小,大的减去小的(记得-1),就搞定了;
代码:

#include<iostream>
#include<cstdio>
using namespace std;
int n,ans=0;
char a;
int fa[30500],fq[35000],fh[35000];
int find(int x)
{
    int u=fa[x];
    if(fa[x]!=x)
    {
        fa[x]=find(fa[x]);
        fq[x]=fq[u]+fq[x];//求位置
    }
    return fa[x];
}
int main()
{
    cin>>n;
    for(int i=1;i<=30000;i++)
        fh[i]=1,fa[i]=i;//父亲数组与后数组
    for(int i=1;i<=n;i++)
    {
       int b,c,u;
       cin>>a>>b>>c;
       int f1=find(b);
       int f2=find(c);
       if(a=='M'&&f1!=f2)fa[f1]=f2,fq[f1]+=fh[f2],fh[f2]+=fh[f1];//合并时前,后数组的处理
       else
       {
            if(f1!=f2)cout<<"-1"<<endl;
               else 
           {
              if(fq[b]>fq[c])cout<<fq[b]-fq[c]-1<<endl;
              else cout<<fq[c]-fq[b]-1<<endl;
           }  
       }
    } 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值