P2881 [USACO07MAR]Ranking the Cows G

P2881 [USACO07MAR]Ranking the Cows G

Title description

FJ wants to rank cows according to their ability to produce milk. There are now N cows (1 ≤ N ≤ 1,000). Through comparison, FJ already knows the relative relationship of M (1 ≤ M ≤ 10,000) pairs. Each pair of relations is denoted as "XY", which means that X's milk production capacity is stronger than Y. Now FJ wants to know how many pairs of relationships he has to investigate at least to complete the entire sequence.

Input format

Line 1: Two space-separated integers: N and M

Lines 2…M+1: Two space-separated integers, respectively: X and Y. Both X and Y are in the range 1…N and describe a comparison where cow X was ranked higher than cow Y.

Output format

Line 1: A single integer that is the minimum value of C.

Sample input and output

Input sample

5 5
2 1
1 5
2 3
1 4
3 4

Sample output

3

Topic analysis

This question mainly examines the application of the graph.
We can use the number of cows as the nodes of the graph and the milk production capacity as the relationship in the graph. You can do the conversion shown in the following figure:
Insert picture description here
Then according to the known conditions: <1,5> < 1,4>,<2,1> can be deduced into <2,4>,<2,5>. A total of 7 kinds of relations. A directed graph has at most s = n*(n-1) /2 kinds of relations. So what is still needed is: s-the seven known;
how to get the known relationship?

Bitset can be used for bit operation , and each node is represented by a bitset. How to use it can click here
bitsetp[maxn];-

  1. Create a binary array of digits.
  2. When initializing, p[i][i]=1, that is, the i-th bit of p[i] is 1. That is, oneself can launch oneself.
  3. Enter 1-5, set p[1][5]=1, then p[1] = …00000 //Count from right to left to the fifth and change the value to 1, which means <1,5>
    enter 1 —4, let p[1][4]=1, then p[1] = …110010.0 // Count from right to left to the fourth and then change the value to 1, which means <1,4>
    enter 2-1 , Let p[2][1]=1, then p[2] = …0011000
    enter 2-3, set p[2][3] =1, then p[2] = …01110
    enter 3-4, let p[3][4]=1, then p[3] = …11000
  4. Judge each bit of each array:
    if(p[i][k])
          p[i] = p[i] | p[j]
    For example, p[2][1]=1, then p[2]= p[2] | p[1]= 001110|110010111110;
    2 is related to 1, and 1 is related to 4 and 5. Through the OR operation, it can be concluded that 2 is also related to 4 and 5.

Reference Code

#include<iostream>
#include<bitset>
using namespace std;
const int maxn = 1005;
bitset<maxn> b[maxn];
int main()
{
    
    
	int n, m,x,y,ans;
	ans = 0;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)//自己能到自己,这个必须初始化,否则后序 | 运算会出错.
	{
    
    
		b[i][i] = 1;
	}
	while (m--)//初始化
	{
    
    
		cin >> x >> y;
		b[x][y] = 1;
	}
	for (int i = 1; i <= n; i++)//遍历
	{
    
    
		for (int j = 1; j <= n; j++)
		{
    
    
			if (b[j][i])
			{
    
    
				b[j] = b[i] | b[j];
			}
			//if (b[i][j])//为啥我这样写不可以呢?
			//{
    
    
			//	b[i] = b[i] | b[j];// 
			//}
		}
	}
	for (int i = 1; i <= n; i++)
	{
    
    
		ans +=b[i].count();//统计已知所有关系
	}
	cout << n * (n - 1) / 2 - (ans - n);//记得最后:所有的关系-(ans-n),因为实际所有关系中,自己到自己忽略,不应计数.
	return 0;
}

Gains

1. The use of bitset
2. Why is the commented part of the code not working? I still have doubts. The big guys can help answer it.

Guess you like

Origin blog.csdn.net/LXYDSF/article/details/114082694