题意:
给定一个有向图,求其中的三元环的数量
分析:
首先可以想到暴力枚举 O(n^3) ,令 a[i][j]=1 表示有一条 i->j 的有向边,令 b[j][i]=1 表示有一条 i->j 的有向边,则可以先暴力:
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j])
for(int z=1;z<=n;z++){
if(a[j][z]&&b[i][z]) ans++;
//表示有一条 z->i->j->z 的三元环
}
}
}
而对于4~5行,其实就是判断 a[j]与 b[i] 内对应位元素是否同时为1的过程,则可以想到用bitset批量操作 ,复杂度降为 O(n^3/W);
代码:
#include<bitset>
#include<cstdio>
#include<iostream>
using namespace std;
const int N = 1500+10;
bitset<N>a[N],b[N],h;
int n;
char s[N];
int main()
{
freopen("triatrip.in","r",stdin);
freopen("triatrip.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
for(int j=1;j<=n;j++)
if(s[j]=='+')
a[i].set(j),b[j].set(i);
}
long long ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(a[i][j])
{
h=a[j]&b[i];
ans+=(long long)h.count();
}
}
cout<<ans/3<<endl;
//一个三元环会被枚举三次:A->B->C->A->B->C
}