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;
    }
  • 相关阅读:
    CompletableFuture java 8新增加异步处理
    Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore , Condition
    怎么让一个不定宽高的div垂直水平居中?
    数组对象方法排序
    Webpack ERROR in Path must be a string. Received undefined
    es6 babel转码器安装配置及常见命令
    使用淘宝镜像cnpm安装Vue.js
    JS中的call()和apply()方法
    placeholder颜色更改
    typeof与js数据类型
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2452044.html
Copyright © 2011-2022 走看看