[传递闭包] P2881 [USACO07MAR]排名的牛Ranking the Cows

题意

FJ想按照奶牛产奶的能力给她们排序。
现在已知有(N (1 le N le 10^3)) 头奶牛。FJ通过比较,已经知道了 (M (1 le M le 10^4)) 对相对关系。
每一对关系表示为 X Y,意指X 的产奶能力强于 Y
现在FJ想要知道,他至少还要调查多少对关系才能完成整个排序。

传递闭包

传递闭包指一个图上的点 (x),是否可以到达除了点 (x) 外的其他点。
传递闭包的储存形式类似邻接矩阵。
传递闭包的实现类似 Floyd

for (int k = 1; k <= n; k++)
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (E[i][k] && E[k][j])
                E[i][j] = 1;

具体说明可见 知乎——算法学习笔记(57): 传递闭包

Code

此题暴力使用传递闭包会 TLE
要使用 bitset 优化。
具体看代码。

const int N = 1005;

bitset<N> g[N];
int n,m;

int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

	cin>>n>>m;
	for(int i=1;i<=n;i++) g[i][i] = 1;
	for(int i=1;i<=m;i++) 
	{
		int u,v;
		cin>>u>>v;
		g[u][v] = 1;
	}

	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
				if(g[i][k])
					g[i] |= g[k];
	
	int ans = 0;
	for(int i=1;i<=n;i++)
		ans += g[i].count();

	cout<<n * (n - 1) / 2 - ans + n << endl;

	return 0;
}
原文地址:https://www.cnblogs.com/BorisDimitri/p/15344272.html