提交时间:2023-12-05 22:39:52

运行 ID: 23951

#include<iostream> #include<cstring> using namespace std; #define int long long const int inf=0x3f3f3f3f3f3f3f3f; #define N 18 int n,m,g[N][N]; namespace sub1{ int head[N],to[N*N],nex[N*N],wei[N*N]; int sta; inline void insert(int u,int v,int w,int id){ to[id]=v; nex[id]=head[u]; head[u]=id; wei[id]=w; } int ans=inf; bool vis1[N],vis2[N]; void dfs1(int nd){ vis1[nd]=true; for(int i=head[nd];i;i=nex[i])if(!vis1[to[i]]&&to[i]&&!(((sta>>((i>>1)-1))^i)&1)){ dfs1(to[i]); } } void dfs2(int nd){ vis2[nd]=true; for(int i=head[nd];i;i=nex[i])if(!vis2[to[i]]&&to[i]&&(((sta>>((i>>1)-1))^i)&1)){ dfs2(to[i]); } } inline void update(int s){ int sum=0; for(int i=1;i<=m;i++){ if(s&(1<<(i-1)))sum+=wei[i<<1|1]; else sum+=wei[i<<1]; } sta=s; memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); dfs1(1); dfs2(1); for(int i=1;i<=n;i++)if(!vis1[i]||!vis2[i])return; ans=min(ans,sum); } int main(){ int now=0; for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++)if(g[i][j]>=0){ now++; insert(i,j,g[i][j],now<<1); insert(j,i,g[j][i],now<<1|1); } } for(int i=0;i<(1<<m);i++)update(i); if(ans<inf)cout<<ans; else cout<<-1; return 0; } } int sum; void init(){ cin>>n; for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)cin>>g[i][j]; for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++)if(g[i][j]>=0)m++; } } int pop[N]; inline int pop_count(int x){ int cnt=0; while(x)cnt++,x-=x&-x; return cnt; } #undef N #define N 11 // int S[N][1<<N],T[N][1<<N]; int F[N][N][1<<N],G[1<<N]; signed main(){ // freopen("anatomy/ex_anatomy2.in","r",stdin); init(); for(int i=0;i<(1<<n);i++)pop[i]=pop_count(i); if(m<=20){ sub1::main(); return 0; } for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(g[i][j]<0)g[i][j]=-inf; for(int i=1;i<=n;i++){ for(int j=1;j<i;j++){ if(g[i][j]>-inf){ sum+=g[i][j]; g[j][i]-=g[i][j]; g[i][j]=0; } } } // for(int i=1;i<=n;i++,cout<<'\n')for(int j=1;j<=n;j++)cout<<g[i][j]<<' '; memset(F,0x3f,sizeof(F)); for(int i=1;i<=n;i++)F[i][i][1<<(i-1)]=0; for(int i=0;i<(1<<n);i++){ for(int s=1;s<=n;s++)if(i&(1<<(s-1))){ for(int t=1;t<=n;t++)if(i&(1<<(t-1))){ if(s!=t||pop[i]==1){ for(int j=1;j<=n;j++)if(!(i&(1<<(j-1)))){ if(g[t][j]>-inf){ int nx=(i|(1<<(j-1))); F[s][j][nx]=min(F[s][j][nx],F[s][t][i]+g[t][j]); } } if(pop[i]>2&&g[t][s]>-inf)F[s][s][i]=min(F[s][s][i],F[s][t][i]+g[t][s]); } } } } memset(G,0x3f,sizeof(G)); for(int i=1;i<=n;i++)G[(1<<(i-1))]=0; for(int i=1;i<(1<<n);i++){ for(int sta=(((1<<n)-1)^i),j=sta;j;j=(j-1)&sta){ for(int s=1;s<=n;s++)if(i&(1<<(s-1))){ for(int t=1;t<=n;t++)if(i&(1<<(t-1))){ G[i|j]=min(G[i|j],G[i]+F[s][t][j|(1<<(s-1))|(1<<(t-1))]); } } } } if(G[(1<<n)-1]<inf-(2e9))cout<<G[(1<<n)-1]+sum; else cout<<-1; // cerr<<((sizeof(F)+sizeof(S)+sizeof(T)+sizeof(G))>>20)<<endl; return 0; }