以下使用 $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;
}
最后修改:2024 年 08 月 28 日
如果觉得我的文章对你有用,请随意赞赏