NC25064 [USACO 2007 Mar G]Ranking the Cows
题目链接
关键点:
1、本题要求求出在题目给出的大小关系下,最少还需要几对大小关系才可以得知所有数字的大小关系
2、首先关于大小关系,比如a>b,b>c可以推出a>c,利用这个性质,对于a>b可以连接一条a到b的边
3、因为题目要求查看任意两点的大小关系,利用floyd算法,枚举起点终点,中间点,若起点到中间点、中间点到起点有边,则将起点到终点连边。这个是否有边是可以用0、1值来代替的。
4、三重循环复杂度过大,且数组的值为01,那么考虑利用01串,b[i]为一个01串,其j位置为1,说明i与j点连边。则当i点的k(中间点)位置为1,那么该中间点为1的位置,即中间点可以到达的点,i也可以到达,那么就将b[i]|=b[k];这样就将循环减成二维了
5、答案对所有的两点间看是否已经确定了关系,即b[i][j] == 1 || b[j][i] == 1,保证不判断相同的两点,第二层循环从i+1开始
完整代码:
# include <iostream>
# include <cstdio>
# include <bitset>
using namespace std;
int n, m;
bitset<1010> b[1010];
int main()
{
cin>>n>>m;
for (int i=1; i<=m; i++)
{
int x, y;
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] == 1)
b[j] |= b[i];
}
}
int cnt = 0;
for (int i=1; i<=n; i++)
{
for (int j=i+1; j<=n; j++)
{
if (!b[i][j] && !b[j][i])
cnt++;
}
}
cout<<cnt<<endl;
return 0;
}