BZOJ 1703 [Usaco2007 Mar]Ranking the Cows 奶牛排名 bitset优化

题意:链接

方法: bitset传递闭包

解析:

显然答案为无序点对的个数。

但是无序点对的个数怎么求呢?

容斥原理。

所有点对个数减去有序点对的个数即为答案。

怎么维护有序点对个数呢?

bitset传递闭包即可。

人生中的第一次rnk1!!!!!!!!!!!

代码:

#include <bitset>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
using namespace std;
int n,m,cnt,cnt2;
int head[N];
int v[N];
bitset<N>b[N];
struct node
{
    int from,to,next;
}edge[N*10];
void init()
{
    memset(head,-1,sizeof(head));
    cnt=1;
}
void edgeadd(int from,int to)
{
    edge[cnt].from=from;
    edge[cnt].to=to;
    edge[cnt].next=head[from];
    head[from]=cnt++;
}
int ret;
void dfs(int x)
{
    v[x]=1;
    for(int i=head[x];i!=-1;i=edge[i].next)
    {
        int to=edge[i].to;
        if(!v[to])
            dfs(to);
        b[x]|=b[to];
    }
}
int ans;
int main()
{
    scanf("%d%d",&n,&m);
    init();
    for(int i=1;i<=n;i++)b[i][i]=1;
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        edgeadd(x,y);
    }
    for(int i=1;i<=n;i++)
    {
        if(!v[i])dfs(i);
    }
    for(int i=1;i<=n;i++)
    {
        ans+=b[i].count();
    }
    printf("%d\n",n*(n-1)/2-ans+n);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-17 02:31:25

BZOJ 1703 [Usaco2007 Mar]Ranking the Cows 奶牛排名 bitset优化的相关文章

Bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名 传递闭包,bitset

1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 323  Solved: 238[Submit][Status][Discuss] Description 农夫约翰有N(1≤N≤1000)头奶牛,每一头奶牛都有一个确定的独一无二的正整数产奶率.约翰想要让这些奶牛按产奶率从高到低排序.    约翰已经比较了M(1≤M≤10000)对奶牛的产奶率,但他发现,他还需要再做一

【BZOJ】1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名

[题意]给定n头牛和m对大小关系,求最坏情况下至少还需要比较几对奶牛的大小(在未确定顺序的奶牛对中随机比较) [算法]floyd求传递闭包 [题解]可达说明大小已知,则不可达点对数量就是最少比较次数. 使用bitset优化传递闭包,复杂度O(n^3 /32). #include<cstdio> #include<bitset> #include<algorithm> using namespace std; const int maxn=1010; int n,m; b

bzoj1703[Usaco2007 Mar]Ranking the Cows 奶牛排名*

bzoj1703[Usaco2007 Mar]Ranking the Cows 奶牛排名 题意: n头奶牛,知道n对奶牛之间的产奶量大小,问想知道所有奶牛产奶量大小顺序至少还需知道几对.n≤1000. 题解: 每个大小关系看为一条有向边,对每头奶牛进行dfs,求每头奶牛可以到的奶牛数和可以到它的奶牛数之和,用n-1减后就是需要和它比较的奶牛数.最后输出(n*(n-1)-所有牛的结果相加)/2即可. 代码: 1 #include <cstdio> 2 #include <cstring&g

【dfs】BZOJ1703-[Usaco2007 Mar]Ranking the Cows 奶牛排名

[题目大意] 农夫约翰有N(1≤N≤1000)头奶牛,每一头奶牛都有一个确定的独一无二的正整数产奶率.约翰想要让这些奶牛按产奶率从高到低排序,约翰已经比较了M(1≤M≤10000)对奶牛的产奶率,但他发现,他还需要再做一张关于另外C对奶牛的产奶率比较,才能推断出所有奶牛的产奶率排序.请帮他确定C的最小值. [思路] 对于M对关系,从产奶率高的往产奶率低的连一条有向边.对于每个节点i,它能抵达的节点的总数即是能比较得出的比它小的奶牛总数. 由于原本总共有N*(N-1)/2对关系,ans=N*(N-

POJ3275 Ranking the Cows floyd的bitset优化

POJ3275 Ranking the Cows 1 #include <iostream> 2 #include <cstdio> 3 #include <bitset> 4 using namespace std; 5 const int maxn = 1005; 6 int n, m; 7 bitset<maxn> maps[maxn]; 8 void floyd() { 9 for (int k = 1; k <= n; k++) { 10 f

bzoj 1637: [Usaco2007 Mar]Balanced Lineup

1637: [Usaco2007 Mar]Balanced Lineup Time Limit: 5 Sec  Memory Limit: 64 MB Description Farmer John 决定给他的奶牛们照一张合影,他让 N (1 ≤ N ≤ 50,000) 头奶牛站成一条直线,每头牛都有它的坐标(范围: 0..1,000,000,000)和种族(0或1). 一直以来 Farmer John 总是喜欢做一些非凡的事,当然这次照相也不例外.他只给一部分牛照相,并且这一组牛的阵容必须是"

BZOJ 1637: [Usaco2007 Mar]Balanced Lineup( sort + 前缀和 )

将 0 变为 -1 , 则只需找区间和为 0 , 即前缀和相同的最长区间 , 记录一下每个前缀和出现的最早和最晚的位置 , 比较一下就 OK 了 ------------------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostr

BZOJ 1704: [Usaco2007 Mar]Face The Right Way 自动转身机( 贪心 )

贪心...先枚举k, 然后从左往右扫一遍, 发现位置p的牛的状态不符合就将 [p, p + k ) 的牛都转身, 假如p + k - 1 已经超过了最右边牛的位置那这个k就不符合要求. 符合要求的就可以用来更新answer.这个贪心的正确性是很显然的.前p - 1头牛都已朝前, 再改动它们也做不到更优; 而要让第p头牛转身, 那就只能让[p, p + k )的牛转身. 考虑如何判断位置p的牛的状态, 我们发现p的状态与它本身和[ p - k - 1, p )这个区间内的牛的转身次数有关, 因为转

[BZOJ] 1639: [Usaco2007 Mar]Monthly Expense 月度开支

1639: [Usaco2007 Mar]Monthly Expense 月度开支 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1077  Solved: 533[Submit][Status][Discuss] Description Farmer John是一个令人惊讶的会计学天才,他已经明白了他可能会花光他的钱,这些钱本来是要维持农场每个月的正常运转的.他已经计算了他以后N(1<=N<=100,000)个工作日中每一天的花费moneyi(1