求助,查了好久不知道哪里错了,只过了5个点
查看原帖
求助,查了好久不知道哪里错了,只过了5个点
123078
C_Z_C楼主2022/1/22 15:29

代码如下

#include <iostream>
#include <cstdio>
#include <climits>
#define ll unsigned long long

using namespace std;

inline int read(){
	int s = 0;
	char c = getchar();
	while(c > '9' || c < '0') c = getchar();
	while(c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
	return s;
}

const int N = 1 << 15;

int n = read(), m = read(), a[20][100005], v[N], V[20][100005];

ll sum[20][N], dp[20][N], inf = LLONG_MAX;

ll min(ll x, ll y){return x < y ? x : y;}

int main(){
	register int i, j, k;
	int s = 1 << n;
	for(i = 1; i <= n; i++)
		for(j = 0; j < s; j++) dp[i][j] = inf;
	for(i = 1; i <= n; i++)
		for(j = 1; j <= m; j++) a[i][j] = read();
	for(i = 1; i <= n; i++){
		int u = read();
		for(j = 1; j <= u; j++){
			int to = read();
			V[i][to] = 1;
			for(k = 1; k < i; k++)
				if(V[k][to]){
					v[(1 << (i - 1)) | (1 << (k - 1))] = 1;
					break;
				}
			for(k = 1; k <= n; k++) sum[k][1 << (i - 1)] += a[k][to];
		}
	}
	for(i = 1; i < s; i++) // v[i][j]表示深度为i线路状态为能否为j
		for(j = 1; j <= n; j++){
			if(i & (1 << (j - 1))) v[i] |= v[i ^ (1 << (j - 1))];
		}
	for(i = 1; i <= n; i++) // sum[i][j]表示深度为i,线路状态为j是的花费
		for(j = 1; j < s; j++){
			int p = 0;
			for(k = 1; k <= n; k++) if(j & (1 << (k - 1))) p++;
			if(p == 1) continue;
			for(k = 1; k <= n; k++)
				if(j & (1 << (k - 1))) sum[i][j] += sum[i][1 << (k - 1)];
		}
	for(i = 1; i <= n; i++){ // 深度
		for(j = 1; j < s; j++){ //前i层的线路状态
			for(k = j; k; k = (k - 1) & j){ //深度为i的线路集合
				if(v[k]) continue;
				dp[i][j] = min(dp[i][j], dp[i - 1][k ^ j] + sum[i][k]);
			}
		}
	}
	cout << dp[n][s - 1];
	return 0;
}
2022/1/22 15:29
加载中...