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 循环,可过此题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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\n", ans); } return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· 手把手教你更优雅的享受 DeepSeek
· AI工具推荐:领先的开源 AI 代码助手——Continue
· 探秘Transformer系列之(2)---总体架构
· V-Control:一个基于 .NET MAUI 的开箱即用的UI组件库
· 乌龟冬眠箱湿度监控系统和AI辅助建议功能的实现