思路与题解思路一致,后13个点WA
#include<bits/stdc++.h>
#define lowbit(x) (x & -x)
#define ll long long
using namespace std;
const int N = 15, M = 1e5 + 5;
int n, m, a[N][M], l2g[1 << N];
vector<int> b[N]; bool p[M], s[1 << N];
ll f[N][1 << N], cnt[N][1 << N];
//l2g[i]表示log2(i)
//s[i]表示在同一层以i的方式修地铁是否可行
//cnt[i][j]表示在第i层以j的方式修地铁的花费
inline int read() {
int x = 0, f = 1; char c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-') f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
bool judge(int x) {
fill(p, p + 1 + n, 0);
for (int i = x; i; i -= lowbit(i)) {
int r = l2g[lowbit(i)] + 1;
for (int j = 0; j < b[r].size(); j++) {
if (p[b[r][j]]) return false;
p[b[r][j]] = true;
}
}
return true;
}
ll calc(int dep, int x) {
ll ans = 0;
for (int i = x; i; i -= lowbit(i)) {
int r = l2g[lowbit(i)] + 1;
for (int j = 0; j < b[r].size(); j++)
ans += a[dep][b[r][j]];
}
return ans;
}
int main() {
n = read(); m = read();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
a[i][j] = read();
for (int i = 1; i <= n; i++) {
int c = read();
for (int j = 1; j <= c; j++)
b[i].push_back(read());
}
for (int i = 0, k = 1; i <= n; i++, k *= 2) l2g[k] = i;
for (int i = 0; i < 1 << n; i++) {
s[i] = judge(i);
if (s[i]) for (int j = 1; j <= n; j++)
cnt[j][i] = calc(j, i);
}//预处理
memset(f, 0x3f, sizeof(f)); f[0][0] = 0;
for (int i = 1; i <= n; i++)
for (int j = 0; j < 1 << n; j++) {
f[i][j] = f[i - 1][j];
for (int k = j; k; k = k - 1 & j)
if (s[k]) f[i][j] = min(f[i][j], f[i - 1][j ^ k] + cnt[i][k]);
}
printf("%lld", f[n][(1 << n) - 1]);
return 0;
}