Week7 homework-A-TT's magic cat

topic

As we all know, TT has a magic cat.

On this day, TT is concentrating on playing the game "Cat and Mouse", but before the game has started, the smart magic cat told the final result of the TT game. TT was very surprised. Not only was he surprised that his little cat could actually talk, but even more surprised that this cute little one had such a magical power?

Magic Cat tells TT that it actually has a game win-loss table with N people and M win-loss relationships. Each win-loss relationship is AB, which means that A can beat B, and the win-loss relationship is transitive. That is, if A beats B and B beats C, then A can also beat C.

TT doesn't believe that his kitty can predict any game, so he wants to know how many pairs of players won and lose can not be known in advance, can you help him?

Input

The first line gives the number of data groups.

The first row of each group of data gives N and M (N, M <= 500).

In the next M lines, AB is given in each line, indicating that A can beat B.

Output

For each set of data, it is impossible to know how many games will win or lose in advance. Note that (a, b) is equivalent to (b, a), that is, each two-tuple is only calculated once.

Sample Input

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

Sample Output

0
0
4

Floyd–Warshall

Insert picture description here

Insert picture description here

Ideas

1. Analysis of the question shows that the question is a problem of seeking a transitive closure, which can be used

Insert picture description here

step0 For each group of data, define a bool array dis[501][501] to store the size relationship, and enter the input size relationship into the dis array (dis[a][b]=1)
step1 call the Floyd function to k, if dis[i][j]=0, and dis[i][k]=1&&dis[k][j]=1, assign dis[i][j] to 1.
step2 Traverse the dis array and calculate all pairs of arrays whose size cannot be determined.

error

1. If you do it directly according to the Floyd algorithm without pruning, it will cause TE errors, so you need to use the Floyd algorithm to match a certain k, if dis[i][k]==0 or dis[i ][j]==1 or dis[k][j]==0 do not need to continue the calculation, but directly use the continue statement to jump to the next loop.
2. When the function parameter is bool** dis, dis[501][501] cannot be passed in, so consider directly replacing the parameter with an array of a certain size.
3. To calculate dis[i][j] for each k, only need to consider whether dis[i][k] and dis[k][j] are all 1, without considering dis[k][i] and dis[ j][k], because this is considered when calculating dis[j][i].
4. When calculating how many pairs are uncertain, calculate once when dis[i][j] and dis[j][i] are all 0

Code

#include<iostream>
using namespace std;
void Floyd(int n,bool dis[501][501])//bool** dis 无法将第二维确定的二维数组传入。
{
    
    
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
		{
    
    
			if(dis[i][k]==0)
				continue;
			for(int j=1;j<=n;j++)
			{
    
    
				if(dis[i][j]==1||dis[k][j]==0)
					continue;
				else
					dis[i][j]=dis[i][k]&&dis[k][j];
			}			
		}

}
int main()
{
    
    
	int n,m,a,b,n1;
	scanf("%d",&n1);
	for(int x=0;x<n1;x++)
	{
    
    
	bool dis[501][501]={
    
    };
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++)
	{
    
    
		scanf("%d%d",&a,&b);
		dis[a][b]=1;		
	}
	Floyd(n,dis);
	int count=0;
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++)
		{
    
    
			if(dis[i][j]==0&&dis[j][i]==0)
				count++;
		}
/*	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=n;j++)
			cout<<dis[i][j]<<' ';	
		cout<<endl;	
	}*/
		
	cout<<count<<endl;		
	}

	return 0;
 } 

Guess you like

Origin blog.csdn.net/alicemh/article/details/105285189