题目意思和求传递闭包完全一样
比如给定
1 ->2
2 ->3
那么自然我们可以得到1 ->3
那么如何来求传递闭包呢?这就需要用到warshall算法,这个算法和floyd求最短路径思想很像,也很好理解
AC代码如下,我做了详细注释:
/*
本题就是一个求传递闭包的问题
*/
#include<iostream>
#include<memory.h>
using namespace std;
int d[555][555];
//warshall算法
int warshall(int n)
{
for(int k = 1;k <= n;k++) //k枚举输的人,相当于floyd中的中转点
{
for(int i = 1;i <= n;i++) //枚举所有人
{
if(d[i][k] == 1) //如果第i个人赢了k这个人
{
for(int j = 1;j <= n;j++) //再看第k号选手赢了哪些人
{
if(d[k][j] == 1) //如果赢了j这个人
d[i][j] = 1; //那么相当于i赢了j这个人
}
}
}
}
int cnt = 0;
for (int i = 1; i <= n; i++)
{
for (int j = i + 1; j <= n; j++)
{
if (d[i][j] == 0 && d[j][i] == 0)
cnt++;
}
}
return cnt;
}
int main()
{
int T;
cin >> T;
while(T-- > 0)
{
memset(d, 0, sizeof(d));
int n, m; //n为人数, m为比赛的数目
cin >> n >> m;
for(int i = 1;i <= m;i++)
{
int a, b;
cin >> a >> b;
d[a][b] = 1;
}
cout << warshall(n) << endl;
//输出图
/*for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
cout << d[i][j] << " ";
}
cout << endl;
}*/
}
return 0;
}