裸的最大团,写了一种 2 ^ (m / 2) * (m / 2)的复杂度的壮压, 应该还有更好的方法。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; int n, m, op; LL e[40]; int a[1<<20], b[1<<20]; string name; set<int> Set; map<string, int> Map; int main() { cin >> n >> m; for(int i = 1; i <= n; i++) { cin >> op; if(op == 1) { Set.clear(); } else { cin >> name; if(Map.find(name) == Map.end()) Map[name] = SZ(Map); int x = Map[name]; for(auto& y : Set) { e[x - 1] |= 1ll << (y - 1); e[y - 1] |= 1ll << (x - 1); } Set.insert(x); } } int c1 = m / 2, c2 = m - c1; for(int S = 1; S < (1 << c1); S++) { int p = __builtin_ctz(S), tmp = 0; a[S] = max(a[S], a[S ^ (1 << p)]); for(int i = 0; i < c1; i++) if(!(e[p]>>i&1)) tmp |= 1 << i; a[S] = max(a[S], a[tmp & (S ^ (1 << p))] + 1); } for(int S = 1; S < (1 << c2); S++) { int p = __builtin_ctz(S), tmp = 0; b[S] = max(b[S], b[S ^ (1 << p)]); for(int i = 0; i < c2; i++) if(!(e[p + c1]>>(i+c1)&1)) tmp |= 1 << i; b[S] = max(b[S], b[tmp & (S ^ (1 << p))] + 1); } int ans = 0; for(int S = 1; S < (1 << c2); S++) { LL tmp = 0; for(int i = 0; i < c2; i++) if(S >> i & 1) tmp |= e[i + c1]; for(int i = 0; i < c1; i++) tmp ^= 1 << i; tmp &= (1 << c1) - 1; ans = max(ans, b[S] + a[tmp]); } printf("%d ", ans); return 0; } /* */