传送门

题意:

  农场主 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<>)的更多相关文章

  1. POJ 3275 Ranking the Cows(传递闭包)【bitset优化Floyd】+【领接表优化Floyd】

    <题目链接> 题目大意:FJ想按照奶牛产奶的能力给她们排序.现在已知有N头奶牛$(1 ≤ N ≤ 1,000)$.FJ通过比较,已经知道了M$1 ≤ M ≤ 10,000$对相对关系.每一 ...

  2. POJ 3275 Ranking the cows ( Floyd求解传递闭包 && Bitset优化 )

    题意 : 给出 N 头牛,以及 M 个某些牛之间的大小关系,问你最少还要确定多少对牛的关系才能将所有的牛按照一定顺序排序起来 分析 : 这些给出的关系想一下就知道是满足传递性的 例如 A > B ...

  3. 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 < ...

  4. POJ 3621:Sightseeing Cows(最优比率环)

    http://poj.org/problem?id=3621 题意:有n个点m条有向边,每个点有一个点权val[i],边有边权w(i, j).找一个环使得Σ(val) / Σ(w)最大,并输出. 思路 ...

  5. POJ 1330 Nearest Common Ancestors (dfs+ST在线算法)

    详细讲解见:https://blog.csdn.net/liangzhaoyang1/article/details/52549822 zz:https://www.cnblogs.com/kuang ...

  6. POJ 1470 Closest Common Ancestors(最近公共祖先 LCA)

    POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description Write a program that takes as input a root ...

  7. POJ 1236 Network of Schools(强连通 Tarjan+缩点)

    POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意:  给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...

  8. POJ 3436 ACM Computer Factory (网络流,最大流)

    POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...

  9. 【POJ 2750】 Potted Flower(线段树套dp)

    [POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4566   ...

随机推荐

  1. 并发模式与 RPS 模式之争,性能压测领域的星球大战

    本文是<如何做好性能压测>系列专题分享的第四期,该专题将从性能压测的设计.实现.执行.监控.问题定位和分析.应用场景等多个纬度对性能压测的全过程进行拆解,以帮助大家构建完整的性能压测的理论 ...

  2. bzoj3899 弦论

    好久没有更blog了啊... 对于一个给定长度为N的字符串,求它的第K小子串是什么. 这是一个SAM的模板题. 我好弱啊这个时候才开始学SAM,才会用指针. 要维护3个东西:每个状态right集合的大 ...

  3. 【JZOJ4761】【NOIP2016提高A组模拟9.7】鼎纹

    题目描述 输入 输出 样例输入 2 3 4 4 2 1100 0110 1100 10 01 10 00 2 2 2 2 11 11 01 10 样例输出 YES NO 数据范围 解法 由于鼎纹中的第 ...

  4. openjudge dp水题记录

    当发现自己竟然不会打dp的时候内心是崩溃的,然后按照一年前的刷题记录刷openjudge,然后发现自己准确率比一年前(刚学信竞两个月时)的准确率低得多,已经没救. 列一下最近打的几道sb题 2985: ...

  5. 【JZOJ1922】【Usaco 2005 NOV Gold】小行星群

    题目描述 Bessie想驾驶她的飞船穿过危险的小行星群,小行星群是一个N×N的网格(1 <= N <= 500),在网格内有K个小行星(1 <= K <= 10,000). 幸 ...

  6. vue vscode属性标签不换行

    "vetur.format.defaultFormatterOptions": { "js-beautify-html": { "wrap_attri ...

  7. 【NS2】Ubuntu 12.04 LTS 中文输入法的安装(转载)

    本文是笔者使用 Ubuntu 操作系统写的第一篇文章!参考了红黑联盟的这篇文章:Ubuntu 12.04中文输入法的安装 安装 Ubuntu 12.04 着实费力一番功夫,老是在用 Ubuntu 来引 ...

  8. Redis源码解析:06整数集合

    整数集合(intset)是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时,Redis就会使用整数集合作为集合键的底层实现. intset可以保存类型为int16_t,i ...

  9. 从零学React Native之02状态机

    本篇文章首发于简书 欢迎关注 之前我们介绍了RN相关的知识: 是时候了解React Native了 从零学React Native之01创建第一个程序 本篇文章主要介绍下下面的知识: 1.简单界面的搭 ...

  10. JSON解析的成长史——原来还可以这么简单

    本文系统介绍,JSON解析的成长史,未经允许,禁止转载. JSON是一种轻量级的数据格式,一般用于数据交互 Android交互数据主要有两种方式:Json和Xml,Xml格式的数据量要比Json格式略 ...