以下使用 $n$ 表示三元组数量,$V$ 表示值域。
对于四元组 $(a,b,c,d)$ 枚举 $a,b$,然后枚举所有形如 $(a,b,x)$ 的三元组两两配对并确认是否满足条件。值域限制 $(a,b,x)$ 至多存在 $2000$ 个,这样的 $(a,b,x)$ 至多出现 $25$ 个,极限计算量级为 $2000^2 \times 25 = 10^8$,可以通过。
实现中直接使用 set
统计三元组,没有进行卡常。
至多有 $O \left( \dfrac{n}{V} \right)$ 个形如 $(a,b,x)$ 的三元组能够达到 $O(V)$ 量级,时间复杂度 $O \left( \dfrac{n}{V} \times V^2 \log V \right) = O(nV\log V)$。
#include<bits/stdc++.h>
using namespace std;
set<int> w[2'005][2'005];
int n,m,ans,t[50'005];
inline void calculate(int a,int b,int x){
for(int i=1;i<=x;i++) for(int j=i+1;j<=x;j++)
if(w[a][t[i]].count(t[j])&&w[b][t[i]].count(t[j])) ++ans;
}
int main(){
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++){
static int x,y,z;
scanf("%d%d%d",&x,&y,&z);
w[x][y].emplace(z);
}
for(int i=1;i<=m;i++)
for(int j=i+1;j<=m;j++) if(!w[i][j].empty()){
int cnt=0;
for(int k:w[i][j]) t[++cnt]=k;
calculate(i,j,cnt);
}
printf("%d\n",ans);
return 0;
}