zoukankan      html  css  js  c++  java
  • 哈理工oj 1360Leyni的国家III解题报告

    链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1360

    这道题的题意是说,一个图中的点相互连接,但是不同的城市之间的连线的警戒等级是不一样的,由低到高分为a,b,c三级,两个点之间可能有多条路径连接,每条单独的路径的警戒级别是这条路径上的警戒级别最高的那条路的级别,而两个城市之间的警戒级别是所有路径当中警戒级别最低级别,这是一道比较难的并查集的问题,关键就在于是什么时候该用哪一个级别的合并函数将两个点合并,很明显如果a,b两点之间有一条级别为a的路相连,那么b和所有与a相连的点中都有一条等级为a的路径相连,而如果a,b之间的连接等级为b那么所有与a相连的等级<=b的点与b点都有一条b等级的路径连接,而b与所有与a相连的等级大于b的点之间都有一条等级大于b的路径连接,对c同理

    View Code
    #include<stdio.h>
    #include<string.h>
    #define N 100005
    int a[3][N];
    int n;
    void init()
    {
        int i;
        for(i=1;i<=n;i++)
        a[0][i]=a[1][i]=a[2][i]=i;
    }
    int find0(int i)
    {
        int r=i;
        while(r!=a[0][r])
        r=a[0][r];
        int t;
        while(i!=a[0][i])
        {
            t=a[0][i];
            a[0][i]=r;
            i=t;
        }
        return r;
    }
    int find1(int i)
    {
        int r=i;
        while(r!=a[1][r])
        r=a[1][r];
        int t;
        while(i!=a[1][i])
        {
            t=a[1][i];
            a[1][i]=r;
            i=t;
        }
        return r;
    }
    int find2(int i)
    {
        int r=i;
        while(r!=a[2][r])
        r=a[2][r];
        int t;
        while(i!=a[2][i])
        {
            t=a[2][i];
            a[2][i]=r;
            i=t;
        }
        return r;
    }
    void uni0(int i,int j)
    {
        int t1=find0(i);
        int t2=find0(j);
        if(t1!=t2)
        a[0][t2]=t1;
    }
    void uni1(int i,int j)
    {
        int t1=find1(i);
        int t2=find1(j);
        if(t1!=t2)
        a[1][t2]=t1;
    }
    void uni2(int i,int j)
    {
        int t1=find2(i);
        int t2=find2(j);
        if(t1!=t2)
        a[2][t2]=t1;
    }
    int main()
    {
        int m,q;
        int t;
        scanf("%d",&t);
        int t1,t2;
        char s[2];
        int i,j,k;
        while(t--)
        {
            scanf("%d%d%d",&n,&m,&q);
            init();
            for(i=0;i<m;i++)
            {
                scanf("%d%d%s",&t1,&t2,s);
                int temp=s[0]-'a';
                if(temp==0)//搞清楚对应不同的情况应该用的合并函数
                {
                    uni0(t1,t2);
                    uni0(find1(t1),t2);
                    uni0(find2(t1),t2);
    
                }
                else if(temp==1)
                {
                    uni1(t1,t2);
                    uni1(find2(t1),t2);
                    uni0(find0(t1),t2);
                }
                else
                {
                    uni2(t1,t2);
                    uni1(find1(t1),t2);
                    uni0(find0(t1),t2);
                }
            }
            for(i=0;i<q;i++)
            {
                scanf("%d%d",&t1,&t2);
                if(find2(t1)==find2(t2))
                {
                    printf("c\n");
                    continue;
                }
                if(find1(t1)==find1(t2))
                {
                    printf("b\n");
                    continue;
                }
                if(find0(t1)==find0(t2))
                {
                    printf("a\n");
                    continue;
                }
                printf("-1\n");
            }
        }
        return 0;
    }
  • 相关阅读:
    2020年面向对象程序设计寒假作业1_实践题
    2020年面向对象程序设计寒假作业1_问答题
    实验5:开源控制器实践——POX
    实验4:开源控制器实践——OpenDaylight
    实验3:OpenFlow协议分析实践
    实验2:Open vSwitch虚拟交换机实践
    第一次个人编程作业
    实验1:SDN拓扑实践
    第一次博客作业
    面向对象程序设计寒假作业3
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2452044.html
Copyright © 2011-2022 走看看