USACO 2007 “March Gold” Ranking the Cows

题目链接:https://www.luogu.org/problemnew/show/P2881

题目链接:https://vjudge.net/problem/POJ-3275

题目大意

  给定标号为 1~N 这 N 个数,在给定 M 组大小关系,求还需要知道多少组大小关系才可以给这组数排序?

分析1(Floyd + bitset)

  总共需要知道 n * (n - 1) / 2 条边,因此只要求一下现在已经有了多少条边,再减一下即可。由于大小关系有传递性,因此计数之前需要求传递闭包。

  直接上 floyd($O(n^3)?$) 会超时,需要用bitset或手动压位,可以在$O(\frac{n^3}{w})?$求出传递闭包,其中w表示字长,为64或32。

代码如下

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  5 #define Rep(i,n) for (int i = 0; i < (n); ++i)
  6 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
  7 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
  8 #define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
  9 #define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
 10 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
 11 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
 12
 13 #define pr(x) cout << #x << " = " << x << "  "
 14 #define prln(x) cout << #x << " = " << x << endl
 15
 16 #define LOWBIT(x) ((x)&(-x))
 17
 18 #define ALL(x) x.begin(),x.end()
 19 #define INS(x) inserter(x,x.begin())
 20
 21 #define ms0(a) memset(a,0,sizeof(a))
 22 #define msI(a) memset(a,inf,sizeof(a))
 23 #define msM(a) memset(a,-1,sizeof(a))
 24
 25 #define MP make_pair
 26 #define PB push_back
 27 #define ft first
 28 #define sd second
 29
 30 template<typename T1, typename T2>
 31 istream &operator>>(istream &in, pair<T1, T2> &p) {
 32     in >> p.first >> p.second;
 33     return in;
 34 }
 35
 36 template<typename T>
 37 istream &operator>>(istream &in, vector<T> &v) {
 38     for (auto &x: v)
 39         in >> x;
 40     return in;
 41 }
 42
 43 template<typename T1, typename T2>
 44 ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
 45     out << "[" << p.first << ", " << p.second << "]" << "\n";
 46     return out;
 47 }
 48
 49 inline int gc(){
 50     static const int BUF = 1e7;
 51     static char buf[BUF], *bg = buf + BUF, *ed = bg;
 52
 53     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
 54     return *bg++;
 55 }
 56
 57 inline int ri(){
 58     int x = 0, f = 1, c = gc();
 59     for(; c<48||c>57; f = c==‘-‘?-1:f, c=gc());
 60     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
 61     return x*f;
 62 }
 63
 64 typedef long long LL;
 65 typedef unsigned long long uLL;
 66 typedef pair< double, double > PDD;
 67 typedef pair< int, int > PII;
 68 typedef pair< int, PII > PIPII;
 69 typedef pair< string, int > PSI;
 70 typedef pair< int, PSI > PIPSI;
 71 typedef set< int > SI;
 72 typedef vector< int > VI;
 73 typedef vector< VI > VVI;
 74 typedef vector< PII > VPII;
 75 typedef map< int, int > MII;
 76 typedef map< int, PII > MIPII;
 77 typedef map< string, int > MSI;
 78 typedef multimap< int, int > MMII;
 79 //typedef unordered_map< int, int > uMII;
 80 typedef pair< LL, LL > PLL;
 81 typedef vector< LL > VL;
 82 typedef vector< VL > VVL;
 83 typedef priority_queue< int > PQIMax;
 84 typedef priority_queue< int, VI, greater< int > > PQIMin;
 85 const double EPS = 1e-10;
 86 const LL inf = 0x7fffffff;
 87 const LL infLL = 0x7fffffffffffffffLL;
 88 const LL mod = 1e9 + 7;
 89 const int maxN = 1e3 + 7;
 90 const LL ONE = 1;
 91 const LL evenBits = 0xaaaaaaaaaaaaaaaa;
 92 const LL oddBits = 0x5555555555555555;
 93
 94 int N, M, cnt;
 95 bitset< maxN > m[maxN];
 96
 97 int main(){
 98     //freopen("MyOutput.txt","w",stdout);
 99     //freopen("input.txt","r",stdin);
100     INIT();
101     N = ri();
102     M = ri();
103     For(i, 1, N) m[i][i] = 1;
104     Rep(i, M) {
105         int x, y;
106         x = ri();
107         y = ri();
108         m[x][y] = 1;
109     }
110
111     For(i, 1, N) For(j, 1, N) if(m[j][i]) m[j] |= m[i];
112     For(i, 1, N) cnt += m[i].count();
113     cnt -= N; // 减去 i->i 的,有 N 条
114
115     printf("%d\n", N * (N - 1) / 2 - cnt);
116     return 0;
117 }

分析2(dfs+ bitset)

  考虑到通过压位过的邻接矩阵求传递闭包时做了很多多余的操作,我们可以用邻接链表来求传递闭包,然后用邻接矩阵计数。复杂度可以降到$O(\frac{n * (n + m)}{w})?$。

代码如下

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  5 #define Rep(i,n) for (int i = 0; i < (n); ++i)
  6 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
  7 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
  8 #define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
  9 #define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
 10 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
 11 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
 12
 13 #define pr(x) cout << #x << " = " << x << "  "
 14 #define prln(x) cout << #x << " = " << x << endl
 15
 16 #define LOWBIT(x) ((x)&(-x))
 17
 18 #define ALL(x) x.begin(),x.end()
 19 #define INS(x) inserter(x,x.begin())
 20
 21 #define ms0(a) memset(a,0,sizeof(a))
 22 #define msI(a) memset(a,inf,sizeof(a))
 23 #define msM(a) memset(a,-1,sizeof(a))
 24
 25 #define MP make_pair
 26 #define PB push_back
 27 #define ft first
 28 #define sd second
 29
 30 template<typename T1, typename T2>
 31 istream &operator>>(istream &in, pair<T1, T2> &p) {
 32     in >> p.first >> p.second;
 33     return in;
 34 }
 35
 36 template<typename T>
 37 istream &operator>>(istream &in, vector<T> &v) {
 38     for (auto &x: v)
 39         in >> x;
 40     return in;
 41 }
 42
 43 template<typename T1, typename T2>
 44 ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
 45     out << "[" << p.first << ", " << p.second << "]" << "\n";
 46     return out;
 47 }
 48
 49 inline int gc(){
 50     static const int BUF = 1e7;
 51     static char buf[BUF], *bg = buf + BUF, *ed = bg;
 52
 53     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
 54     return *bg++;
 55 }
 56
 57 inline int ri(){
 58     int x = 0, f = 1, c = gc();
 59     for(; c<48||c>57; f = c==‘-‘?-1:f, c=gc());
 60     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
 61     return x*f;
 62 }
 63
 64 typedef long long LL;
 65 typedef unsigned long long uLL;
 66 typedef pair< double, double > PDD;
 67 typedef pair< int, int > PII;
 68 typedef pair< int, PII > PIPII;
 69 typedef pair< string, int > PSI;
 70 typedef pair< int, PSI > PIPSI;
 71 typedef set< int > SI;
 72 typedef vector< int > VI;
 73 typedef vector< VI > VVI;
 74 typedef vector< PII > VPII;
 75 typedef map< int, int > MII;
 76 typedef map< int, PII > MIPII;
 77 typedef map< string, int > MSI;
 78 typedef multimap< int, int > MMII;
 79 //typedef unordered_map< int, int > uMII;
 80 typedef pair< LL, LL > PLL;
 81 typedef vector< LL > VL;
 82 typedef vector< VL > VVL;
 83 typedef priority_queue< int > PQIMax;
 84 typedef priority_queue< int, VI, greater< int > > PQIMin;
 85 const double EPS = 1e-10;
 86 const LL inf = 0x7fffffff;
 87 const LL infLL = 0x7fffffffffffffffLL;
 88 const LL mod = 1e9 + 7;
 89 const int maxN = 1e3 + 7;
 90 const LL ONE = 1;
 91 const LL evenBits = 0xaaaaaaaaaaaaaaaa;
 92 const LL oddBits = 0x5555555555555555;
 93
 94 struct Edge{
 95     int from, to;
 96 };
 97
 98 struct Vertex{
 99     VI edges;
100 };
101
102 int N, M, cnt;
103 bitset< maxN > m[maxN], vis;
104 Edge e[maxN << 4];
105 int elen;
106 Vertex v[maxN];
107
108 // 找到 x 号节点所能到达的所有节点
109 void dfs(int x) {
110     vis[x] = 1;
111     foreach(i, v[x].edges) { // 结果取决于 x 的孩子节点所能到达的节点,此处相当于 m[x][y] = 1
112         int y = e[*i].to;
113         if(!vis[y]) dfs(y);
114         m[x] |= m[y];
115     }
116 }
117
118 int main(){
119     //freopen("MyOutput.txt","w",stdout);
120     //freopen("input.txt","r",stdin);
121     INIT();
122     N = ri();
123     M = ri();
124     For(i, 1, N) m[i][i] = 1;
125     Rep(i, M) {
126         int x, y;
127         x = ri();
128         y = ri();
129         e[++elen].from = x;
130         e[elen].to = y;
131         v[x].edges.PB(elen);
132     }
133
134     For(i, 1, N) if(!vis[i]) dfs(i);
135     For(i, 1, N) cnt += m[i].count();
136     cnt -= N; // 减去 i->i 的,有 N 条
137
138     printf("%d\n", N * (N - 1) / 2 - cnt);
139     return 0;
140 }

原文地址:https://www.cnblogs.com/zaq19970105/p/11005295.html

时间: 2024-10-31 02:11:25

USACO 2007 “March Gold” Ranking the Cows的相关文章

【POJ3612】【USACO 2007 Nov Gold 】1.Telephone Wire 动规

题意: 给出若干棵树的高度,你可以进行一种操作:把某棵树增高h,花费为h*h. 操作完成后连线,两棵树间花费为高度差*定值c. 求两种花费加和最小值. 题解: 跟NOIP2014 D1T3很像. 暴力动规是O(1*10^9)会T 所以单调队列一下,每颗树扫两遍结束. 完事,看水代码吧. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N

USACO翻译:USACO 2014 MARCH GOLD P2 Sabotage

1.破坏{DOLD题2} sabotage.pas/c/cpp [问题描述] 农夫约翰的头号敌人保罗决定破坏农民约翰的挤奶设备.挤奶设备排成一行,共N(3<= N <=100000)台挤奶机,其中第i个台挤奶机生产M_i单位(1 <= M_i<=10,000)的牛奶. 保罗计划切断一段连续的挤奶机,从第i台挤奶机到第j台挤奶机(2<= i<= j<= N-1).注意,他不希望断开第一台或最后一台挤奶机,因为这将会使他的计划太容易被发现.保罗的目标是让其余机器的平均

【POJ3613】【USACO 2007 Nov Gold】 2.Cow Relays 矩阵乘法?

题意:给你一个m条边的图,求s到t的正好用k条边的最短路. (输入k,t,s,t) 题解: 先说说暴力. 动规f[k][i][j]表示i到j经过k条边的最短路,然后外层循环k一遍遍跑最后出解. 显然大概率T. 然后有一种思路: 我们可以动规求得f[k][i][j]表示i到j经过k条边的最短路,然后再求g[i]表示从终点走i步回到终点的最短路. 这样我们就可以乱搞过了.(没写,也没细想) 再之后是正解: 我们可以利用类似于快速幂的方法求f[i][j]表示i到j正好用多少多少步. 然后思想是使用边数

【POJ3614】【USACO 2007 Nov Gold】 3.Sunscreen 贪心

题意: 有若干个区间,若干种数,每个数告诉你有多少个. 然后一个数可以被放到一个x∈该区间 的区间,问最多有多少个区间可以被放. 题解: 显然我们可以用二分图最大匹配做,水题. 但是此题有别的技巧. 就是我们可以贪心进行处理. 首先我们考虑到需要将两种数都排个序. 然后再进行贪心. 一种错误的贪心法是单调队列式贪心,就是记录个top,然后单调往后推. 这个不仔细想还不知道它是错的. 额,至于卡它的数据,,我可以提供给你一个错误代码和一个拍子,你们可以自己拍一组数据出来,很高效. 这里贴一份错误代

【POJ3612】【USACO 2007 Nov Gold】 1.Telephone Wire 动态调节

意甲冠军: 一些树高给出.行一种操作:把某棵树增高h,花费为h*h. 操作完毕后连线,两棵树间花费为高度差*定值c. 求两种花费加和最小值. 题解: 跟NOIP2014 D1T3非常像. 暴力动规是O(1*10^9)会T 所以单调队列一下,每颗树扫两遍结束. 完事,看水代码吧. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 101

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)对奶牛的产奶率,但他发现,他还需要再做一

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

USACO翻译:USACO 2014 MARCH Silver三题

USACO 2014 MARCH 一.题目概览 中文题目名称 农田灌溉 懒牛 牛叫 英文题目名称 irrigation lazy mooomoo 可执行文件名 irrigation lazy mooomoo 输入文件名 irrigation.in lazy.in mooomoo.in 输出文件名 irrigation.out lazy.out mooomoo.out 每个测试点时限 1秒 1秒 1秒 测试点数目 10 10 10 每个测试点分值 10 10 10 比较方式 全文比较 全文比较 全

POJ-3275:Ranking the Cows(Floyd、bitset)

Ranking the Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3301   Accepted: 1511 Description Each of Farmer John's N cows (1 ≤ N ≤ 1,000) produces milk at a different positive rate, and FJ would like to order his cows according to