传送门

题意:

  农场主 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. JS实现AES加密并与PHP互通的方法分析

    <script type="text/javascript" src="/CryptoJS/aes.js"></script><s ...

  2. Spring_使用(JDBC)

    Spring_对JDBC的支持 使用JdbcTemplate更新数据库 导入jar包 创建applicationcontext.xml <?xml version="1.0" ...

  3. Struts → 《Struts2程序开发》教材大纲

  4. iOS开发 底层抛析运行循环—— RunLoop

    http://blog.csdn.net/zc639143029/article/details/50012527 一.RunLoop基本概念 概念:程序的运行循环,通俗的来说就是跑圈. 1. 基本作 ...

  5. oracle怎么捕获用户登录信息,如SID,IP地址等

    可以利用登录触发器,如 CREATE OR REPLACE TRIGGER tr_login_record AFTER logon ON DATABASE DECLARE miUserSid NUMB ...

  6. 【Linux】根目录命名的意义

    1./bin :获得最小的系统可操作性所需要的命令2./boot :内核和加载内核所需的文件3./dev :终端.磁盘.调制解调器等的设备项4./etc :关键的启动文件和配置文件5./home :用 ...

  7. Android 高仿微信支付键盘

    现在很多app的支付.输入密码功能,都已经开始使用自定义数字键盘,不仅更加方便.其效果着实精致. 下面带着大家学习下,如何高仿微信的数字键盘,可以拿来直接用在自身的项目中. 先看下效果图: 1. 自定 ...

  8. iOS runtime整理

    iOS利用Runtime自定义控制器POP手势动画 http://www.cocoachina.com/ios/20150401/11459.html  Objective C运行时(runtime) ...

  9. 8.5打包libgdx为一个桌面程序(jar包)

    简陋的地图编辑终于做好了,于是要开始制作地图了,想导出为一个windows下可用的程序,让熟人代做地图,然后找人问了下打包流程,其实跟普通java打包为jar没什么区别,记录如下: 导出类型选第三个 ...

  10. LeetCode70 Climbing Stairs

    题目: You are climbing a stair case. It takes n steps to reach to the top. Each time you can either cl ...