zoukankan      html  css  js  c++  java
  • POJ 3275 Ranking the cows ( Floyd求解传递闭包 && Bitset优化 )

    题意 : 给出 N 头牛,以及 M 个某些牛之间的大小关系,问你最少还要确定多少对牛的关系才能将所有的牛按照一定顺序排序起来

    分析 :

    这些给出的关系想一下就知道是满足传递性的

    例如 A > B && B > C 可以推出  A > C

    也就是说如果用数组 arr[i][j] = true 表示牛 i 和 牛 j 有关系

    那么 arr[i][k] = true && arr[k][j]  就可以推出 arr[i][j] = true

    如果接触过 Floyd 算法就知道这很像算法里面的松弛操作

    所以可以用 Floyd 求出所有传递闭包,最后看看还有矩阵中

    除了 i ≠ j 的位置满足 arr[i][j] = false && arr[j][i] = false 答案就 + 1

    注意这里必须是 arr[i][j] = arr[j][i] = false 单个 arr[i][j] = false 是不行的

    因为如果 arr[i][j] = true 也就是我们确定了 i > j 这种关系

    而一旦知道了这个关系,我们就可以确定 j < i 也就是 arr[j][i] = true

    但是普通的 Floyd 算法的时间复杂度是 O( n3 ) 的,过不了这题的数据范围

    这时候有一个套路,就是使用 std::bitset 优化

    我们将关系矩阵存到一个 bitset 数组中 ( define == > bitset<maxn> arr[maxn] )

    然后如果 arr[i][k] = true 那么也就是说 i 可以和 k 确定关系

    那么 i 必定可以和关系矩阵中的第 k 行确定关系,所以直接进行或运算

    即 if( arr[i][k] == true ) arr[i] |= arr[k] 

    这样就减少了一个 for 循环,可过此题

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e3 + 10;
    bitset<maxn> arr[maxn];
    int main(void)
    {
        int N, M;
        while(~scanf("%d %d", &N, &M)){
    
            for(int i=0; i<=N; i++)
                arr[i].reset(); ///将 bitset 的位全部变成 0
    
            int u, v; //u->v
            while(M--){
                scanf("%d %d", &u, &v);
                arr[u][v] = 1; /// u 能和 v 确定关系
            }
    
            for(int k=1; k<=N; k++)
                for(int i=1; i<=N; i++)
                    if(arr[i][k])
                        arr[i] |= arr[k];
    
            int ans = 0;
            for(int i=1; i<=N; i++) ///这里我们只要遍历一个上三角就可以了
                for(int j=i+1; j<=N; j++)
                    if(arr[i][j] == 0 &&
                       arr[j][i] == 0) ans++;
    
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Clien
    docker pull下载镜像报错Get https://registry-1.docker.io/v2/library/centos/manifests/latest:..... timeout
    Maven 插件之 docker-maven-plugin 的使用
    Windows10下的docker安装与入门 (一)使用docker toolbox安装docker
    解决IntelliJ IDEA 创建Maven项目速度慢问题
    svn检出maven项目的步骤
    学习RabbitMQ(三):AMQP事务机制
    TX-LCN分布式事务Demo实战
    SQLite -创建数据库
    备忘录模式
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/8529890.html
Copyright © 2011-2022 走看看