版权声明:_ https://blog.csdn.net/lunch__/article/details/82224428
这个题也不是很难,就是个一般的三元环计数
今天用一种奇怪的做法 来优化
是个很好用的东西 类似于一个二进制数 但是时间和空间消耗都很小
它大概有以下操作
所有的位运算,例如 还有&运算
一些相关的函数
#include<iostream>
#include<bitset>
std::bitset<233> f;
int main() {
f.size(); //bitset的大小 在这里就是233
f.count(); //bitset 中二进制1的个数
f.set(); //所有位都设为1
f.reset(); //所有的位都设为0
f.set(u); //把第u位设为1
f.reset(u); //把第u位设为0
f.any(); //是否存在一位是1
f[x]; // 访问第x位的元素
f.flip(); //取反所有位
f.flip(x); //取反第x位
f.to_ulong(); //转化为unsigned long 并返回
}
反正这个东西自带一个 的常数,可以优化一些过不了的东西
位的机器上 这样子 的算法就可以优化到 就能跑 了
这个题加上 的做法之后就可以直接跑最暴力的做法了
首先把每个点的出边和入边都用 存下来
然后暴力枚举两个点, , 把 的入边和 的出边进行与操作后里面 的个数加入答案就够了。
因为三元环每条边都被枚举到了一次 最后答案除个3就好了
记得开
复杂度
Codes
#include<bits/stdc++.h>
using namespace std;
const int N = 1500 + 10;
bitset<N> in[N], out[N];
int a[N][N], ans;
int main() {
freopen("triatrip.in", "r", stdin);
freopen("triatrip.out", "w", stdout);
int n; long long ans = 0; char c;
scanf("%d", &n);
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= n; ++ j) {
cin >> c;
if(c == '+') {
a[i][j] = 1;
out[i][j] = 1;
in[j][i] = 1;
}
}
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= n; ++ j)
if(a[i][j])
ans += (out[j] & in[i]).count();
cout << ans / 3 << endl;
return 0;
}