开始 2023-12-05 22:37:15

【2024省选前】20231205更正

结束 2023-12-31 00:00:00
Contest is over.
当前 2024-11-01 10:31:09

T1
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;
typedef long long LL;
const int CN=25;
int N,G[CN][CN];
int f[1<<17][19][19][2];
template<typename T> inline bool chkmin(T &x,const T y){
	return (x>y)?(x=y,1):0;
}
int main(){

	scanf("%d",&N);
	for(int i=1;i<=N;++i){
		for(int j=1;j<=N;++j){
			scanf("%d",&G[i][j]);
		}
	}
	int ans=0;
	for(int i=1;i<=N;++i){
		for(int j=i+1;j<=N;++j){
			if(G[i][j]!=-1){
				int mn=min(G[i][j],G[j][i]);
				G[i][j]-=mn;
				G[j][i]-=mn;
				ans+=mn;
			}
		}
	}
	memset(f,0x3f,2888 << N);
	f[1][1][1][0]=0;
	f[1][1][1][1]=0;
	for(int s=1;s<(1<<N);++s){
		int mincost=1e9;
		for(int i=1;i<=N;++i){ // 从i开始
			for(int j=1;j<=N;++j){ // 需要到j
				int ho=f[s][i][j][0],ha=f[s][i][j][1];
				// 记得跳过没用的转移。。。
				if(ho>1e9&&ha>1e9){
					continue;
				}
				if(i!=j){
					for(int k=1;k<=N;++k){ // 现在把路径走向k
						// 从i走到k
						if(G[i][k]!=-1){
							if(((s>>(k-1))&1)==0||k==j){
								if(k!=j){
									chkmin(f[s|(1<<(k-1))][k][j][1],ho+G[i][k]);
								}
								chkmin(f[s|(1<<(k-1))][k][j][1],ha+G[i][k]);
							}
						}
					}
				}
			}
		}
		for(int i=1;i<=N;++i){ // 注意搞清楚转移顺序
			chkmin(mincost,f[s][i][i][1]);
			chkmin(mincost,f[s][i][i][0]);
		}
		if(mincost>=1e9){
			continue;
		}
		for(int k=1;k<=N;++k){
			if(((s>>(k-1))&1)==0){
				continue;
			}
			for(int i=1;i<=N;++i){
				if(((s>>(i-1))&1)||G[k][i]==-1){
					continue;
				}
				int hoha=s|(1<<(i-1));
				int tmp=G[k][i];
				for(int j=1;j<=N;++j){
					if(((s>>(j-1))&1)==0){
						continue;
					}
					if(k==j){
						chkmin(f[hoha][i][j][0],mincost+tmp);
					}else{
						chkmin(f[hoha][i][j][1],mincost+tmp);
					}
				}
			}
		}
	}
	int ans1=0x3f3f3f3f;
	for(int i=1;i<=N;++i){
		chkmin(ans1,f[(1<<N)-1][i][i][1]);
		chkmin(ans1,f[(1<<N)-1][i][i][0]);
	}
	if(ans1>=1e9){
		printf("-1\n");
	}else{
		printf("%d\n",ans+ans1);
	}
	return 0;
}

admin  •  10个月前

比赛已结束。