一般是会给出一些胜负关系,然后我们就可以通过flody来传递这种胜负关系。
比如3>2,2>0,所以我们就可以得到3>0。
但是因为flody的时空间复杂度都比较高,所以我们有时候可能还得加一些优化。
大意:
已知一些胜负关系,试求出能确定排名的牛的个数
思路:
可以用一个bitset优化邻接矩阵,如果两只牛有关系,让胜者到负者的距离变成1.然后跑一遍flody,最后遍历时只要统计一下每只牛是否对其他n-1只牛的关系都已知即可。
数据量就100,随便怎么搞。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn=110;
ll n,m;
bitset<maxn> mas[maxn];
ll a,b;
int main()
{
cin>>n>>m;
for(int i=0;i<=n;++i) mas[i].reset();
for(int i=1;i<=m;++i){
cin>>a>>b;
mas[a][b]=1;
//mas[b][a]=1;
}
for(int j=1;j<=n;++j){
for(int i=1;i<=n;++i){
if(i==j) continue;
if(!mas[i][j]) continue;
mas[i]|=mas[j];
}
}
ll ans=0;
ll cnt[110];
memset(cnt,0,sizeof cnt);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(mas[i][j]){
cnt[i]++;
cnt[j]++;
if(cnt[i]==n-1) ans++;
if(cnt[j]==n-1) ans++;
}
}
}
// for(int i=1;i<=n;++i){
// for(int j=1;j<=n;++j){
// cout<<mas[i][j]<<" ";
// }
// cout<<endl;
// }
cout<<ans<<endl;
return 0;
}
此题与上体的区别就是数据范围大了点,那么这个使没办法用裸的flody过的,因为n3的复杂度那是会超时的。本来是
mas[i][j] |= (mas[i][k] & mas[k][j]);
需要用中间点来过渡,
现在省掉这一步,让二者直接对标。因为我们只传递胜的关系,负的关系是没有被记录的,那么最后统计时只要保证map[i][j]|mas[j][i]==0即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn=1010;
ll n,m;
bitset<maxn> mas[maxn];
ll a,b;
int main()
{
cin>>n>>m;
for(int i=0;i<=n;++i) mas[i].reset();
for(int i=1;i<=m;++i){
cin>>a>>b;
mas[a][b]=1;
}
for(int j=1;j<=n;++j){
for(int i=1;i<=n;++i){
if(i==j) continue;
if(!mas[i][j]) continue;
mas[i]|=mas[j];
}
}
ll ans=0;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(mas[i][j]) ans++;
}
}
cout<<n*(n-1)/2-ans<<endl;
return 0;
}