zoukankan      html  css  js  c++  java
  • noi2002银河英雄传说(并查集)

    首先表示对C++读入读出问题复杂程度的敬畏,看了好多没讲明白的,本题用cin竟然过不了评测,搞scanf的读入搞了好久....

    本题确实是一道经典的并查集题型,不多讲,拿来练练手用的(其中经历很惨)

    用pre[i]表示i到其父节点f[i]之间排几个(父节点算1个)

    f[i]表示i的父节点

    num[i]表示i的队伍中一共有多少人

    大致即 利用父节点与该点距离进行迭代的过程,即pre[x]=pre[x]+pre[f[x]]; 然后每次调整队伍时只要将父节点的位置搞清楚了,其他点都可以根据与父节点关系计算出来

    /*看来对于c++这门语言见解不够,或者说c++确实不好用*/
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    int f[30000],pre[30000],num[30000];
    using namespace std;
    int find(int x){
        if (f[x]==x) return(x);
        find(f[x]);
        pre[x]+=pre[f[x]];
        f[x]=f[f[x]];
        return(f[x]);
    }
    int main()
    {
        int n,i,j,k,a,b,fa,fb;
        char c;
        cin>>n;
        for(k=1;k<=30000;k++){
            f[k]=k;
            num[k]=1;
        }
        for(k=1;k<=n;k++){
            while (getchar()!='
    ');//读入问题至今觉得c++的cin和scanf都相当不好用,可能有的作用不知道,但是没找到真正讲得明白其原理的文章;  只能表示pascal的read,readln的强大
            scanf("%c",&c);
            scanf("%d%d",&a,&b);
            fa=find(a);fb=find(b);
            if(c=='M'){
                f[fa]=fb;
                pre[fa]=num[fb];
                num[fb]+=num[fa];
            }
            if(c=='C'){
                if(fa==fb){
                    printf("%d
    ",((int)abs(pre[a]-pre[b]))-1);//很奇怪的地方,若abs不用int竟然abs返回值变成0,不知为什么?
                }else printf("-1
    ");
            }
        }
        return 0;
    }



    那么多的束缚,我不曾放弃过;那么多的险阻,我不曾倒下过。
  • 相关阅读:
    CDK上安装kube-dashboard
    JBoss入门
    CDK安装
    minishift安装
    Openshift中Configmap的使用
    每天5分钟玩转Docker
    Openshift初步学习问题集
    pyinstaller深入使用,打包指定模块,打包静态文件
    firefox 开启安全禁用端口
    使用VirtualBox把IMG文件转换为VDI文件
  • 原文地址:https://www.cnblogs.com/Mathics/p/3681190.html
Copyright © 2011-2022 走看看