poj 3275 "Ranking the Cows"(DFS or Floyd+bitset<>)
题意:
农场主 FJ 有 n 头奶牛,现在给你 m 对关系(x,y)表示奶牛x的产奶速率高于奶牛y;
FJ 想按照奶牛的产奶速率由高到低排列这些奶牛,但是这 m 对关系可能不能精确确定这 n 头奶牛的关系;
问最少需要额外增加多少对关系使得可以确定这 n 头奶牛的顺序;
题解:
之所以做这道题,是因为在补CF的题时用到了bitset<>;
搜这个容器的用法是看到了一篇标题为POJ-3275:奶牛排序Ranking the Cows(Floyd、bitset)的文章;
正好拿着道题练练bitset<>;
但是一做,发现,这道题和省赛的L题好像啊,做法完全相同,只是在输出结果上处理了一下;
下午在补一下如何用bitset<>做这道题,先贴上DFS暴力AC代码;
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=1e3+; int n,m;
int num;
int head[maxn];
struct Edge
{
int to;
int next;
}G[maxn**];
void addEdge(int u,int v)
{
G[num]={v,head[u]};
head[u]=num++;
}
bool vis[maxn]; int DFS(int u)
{
int ans=;
vis[u]=true;
for(int i=head[u];~i;i=G[i].next)
{
int v=G[i].to;
if(vis[v] || (i&))
continue;
ans += DFS(v);
}
return ans;
}
int RDFS(int u)
{
int ans=;
vis[u]=true;
for(int i=head[u];~i;i=G[i].next)
{
int v=G[i].to;
if(vis[v] || !(i&))
continue;
ans += RDFS(v);
}
return ans;
}
int Solve()
{
int ans=;
for(int i=;i <= n;++i)
{
mem(vis,false);
int t1=DFS(i);
mem(vis,false);
int t2=RDFS(i);
///第i头奶牛可以确定的奶牛个数为t1+t2-1
ans += n-(t1+t2-);
}
return ans>>;
}
void Init()
{
num=;
mem(head,-);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
Init();
for(int i=;i <= m;++i)
{
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
}
printf("%d\n",Solve());
}
return ;
}
思路2:(来自上述链接文章)
确定这 n 头奶牛的顺序需要 n*(n-1)/2 对关系;
(X,Y)代表 rankX > rankY
已知关系 (X,Y),(Y,Z),那么,根据传递性可得隐藏关系(X,Z);
如何根据给出的m条关系找到所有的隐藏关系呢?
Floyd传递闭包;
AC代码1:
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=1e3+; int n,m;
bool e[maxn][maxn];
vector<int >in[maxn],out[maxn];
///in[u]:指向u的节点,out[u]:u指出去的节点 int Solve()
{
int ans=;
for(int k=;k <= n;++k)
{
for(int i=;i < in[k].size();++i)
{
for(int j=;j < out[k].size();++j)
{
int u=in[k][i];
int v=out[k][j];
if(!e[u][v])///隐藏关系u->v
{
e[u][v]=true;
out[u].push_back(v);
in[v].push_back(u);
ans++;
}
}
}
}
///m:已知关系对
///ans:隐藏关系对
return n*(n-)/-m-ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i <= m;++i)
{
int u,v;
scanf("%d%d",&u,&v);
in[v].push_back(u);
out[u].push_back(v);
e[u][v]=true;
}
printf("%d\n",Solve()); return ;
}
另一种写法就是用到了bitset<>容器;
bitset<>_bit[];
对于输入的关系<u,v>;
_bit[u].set(v);//将第v为置位1,表示有一条u->v的边
如何找到所有的隐藏关系呢?
for(int i=;i <= n;++i)
for(int j=;j <= n;++j)
if(_bit[j][i])
_bit[j] |= _bit[i];///让j节点指向i节点所有指出去的边
晚上一直困惑,为什么将if()及其之后的语句改为
if(_bit[i][j])
_bit[i] |= _bit[j];
就wa了,找了许久,终于找到了;
对于如下关系:
(①,③) , (③,②) , (②,④)
(①->③->②->④)
当 i = 1 时,如果按照更改后的写法,①只会更新出<①,②>而不会更新出关系<①,④>(纸上画一下就出来了);
所以说,要更新内层循环的节点,这样更新的彻底;
AC代码2:
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<bitset>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=1e3+; int n,m;
bitset<maxn>_bit[maxn]; int Solve()
{
for(int i=;i <= n;++i)
for(int j=;j <= n;++j)
if(_bit[j][i])
_bit[j] |= _bit[i];///让j节点指向i节点所有指出去的边 int ans=;
for(int i=;i <= n;++i)
ans += _bit[i].count(); ///ans:m对已有关系对+隐藏关系对
return n*(n-)/-ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i <= m;++i)
{
int u,v;
scanf("%d%d",&u,&v);
_bit[u].set(v);
}
printf("%d\n",Solve()); return ;
}
poj 3275 "Ranking the Cows"(DFS or Floyd+bitset<>)的更多相关文章
- POJ 3275 Ranking the Cows(传递闭包)【bitset优化Floyd】+【领接表优化Floyd】
<题目链接> 题目大意:FJ想按照奶牛产奶的能力给她们排序.现在已知有N头奶牛$(1 ≤ N ≤ 1,000)$.FJ通过比较,已经知道了M$1 ≤ M ≤ 10,000$对相对关系.每一 ...
- POJ 3275 Ranking the cows ( Floyd求解传递闭包 && Bitset优化 )
题意 : 给出 N 头牛,以及 M 个某些牛之间的大小关系,问你最少还要确定多少对牛的关系才能将所有的牛按照一定顺序排序起来 分析 : 这些给出的关系想一下就知道是满足传递性的 例如 A > B ...
- POJ 3187 Backward Digit Sums (dfs,杨辉三角形性质)
FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N < ...
- POJ 3621:Sightseeing Cows(最优比率环)
http://poj.org/problem?id=3621 题意:有n个点m条有向边,每个点有一个点权val[i],边有边权w(i, j).找一个环使得Σ(val) / Σ(w)最大,并输出. 思路 ...
- POJ 1330 Nearest Common Ancestors (dfs+ST在线算法)
详细讲解见:https://blog.csdn.net/liangzhaoyang1/article/details/52549822 zz:https://www.cnblogs.com/kuang ...
- POJ 1470 Closest Common Ancestors(最近公共祖先 LCA)
POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description Write a program that takes as input a root ...
- POJ 1236 Network of Schools(强连通 Tarjan+缩点)
POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意: 给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...
- POJ 3436 ACM Computer Factory (网络流,最大流)
POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...
- 【POJ 2750】 Potted Flower(线段树套dp)
[POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4566 ...
随机推荐
- less知识点总结(二)
变量:以@开头,由于变量只能定义一次,其本质就是“常量”. @nice-blue: #5B83AD; @light-blue: @nice-blue + #; #header { color: @li ...
- jquery.dataTables的探索之路-服务端分页配置
最近闲来无事想研究下数据表格,因为之前接触过layui和bootstrap的数据表格,本着能学多少学多少的学习态度,学习下dataTables的服务端分页配置.特与同学们一块分享下从中遇到的问题和解决 ...
- Android手机控制电脑撸出HelloWorld
最近在开发一个远程办公的软件. 昨天在手机调通,并且成功通过手机打开电脑上的Eclipse撸出来一个HelloWorld. 也许不久的将来, 下班后,拿着手机在家写代码了.工作时间直接变成24/24 ...
- Android LruCache源码简介
package android.util; import java.util.LinkedHashMap; import java.util.Map; /** * A cache that holds ...
- django2.0基础
一.安装与项目的创建 1.安装 pip install django 2.查看版本 python -m django --version 3.创建项目 django-admin startprojec ...
- MUI - 基于plus.downloader的图片懒加载功能,支持本地缓存
基于plus.downloader的图片懒加载功能,支持本地缓存 简单说一下 在app中,对一些变动不频繁的图片数据(如个人头像等),是需要存储在本地的.我相信这对大多数的app都是强需求的. 怎么使 ...
- Android实战:手把手实现“捧腹网”APP(三)-----UI实现,逻辑实现
Android实战:手把手实现"捧腹网"APP(一)-–捧腹网网页分析.数据获取 Android实战:手把手实现"捧腹网"APP(二)-–捧腹APP原型设计.实 ...
- C++继承与构造函数、复制控制
每个派生类对象由派生类中定义的(非static)成员加上一个或多个基类子对象构成,因此,当构造.复制.赋值和撤销派生类型对象时,也会构造.复制.赋值和撤销这些基类子对象. 构造函数和复制控制成员不能继 ...
- 通过反射 拿到方法 Day25
package com.sxt.method1; /* * 通过反射 拿到方法 */ import java.lang.reflect.Method; import java.lang.reflect ...
- Python基础:08列表解析与生成器表达式
一:列表解析 列表解析(List comprehensions)来自函数式编程语言Haskell .它可以用来动态地创建列表.它在 Python 2.0 中被加入. 列表解析的语法: [exp ...