萌新求调:一直WA on #1 #2 #4 64分
查看原帖
萌新求调:一直WA on #1 #2 #4 64分
438461
liu_chen_hao楼主2023/7/17 14:49

如题,f[i][j][s]表示从i出发到j停止经过了s这个状态的点的最小代价,g[s]表示把s中的点包含到最终形成的强连通图所需最小代价。

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define ll long long
using namespace std;
const int N=12;
const int mod=998244353;
const int inf=0x3f3f3f3f;
const ll  INF=0x3f3f3f3f3f3f3f3f;

struct nod {
	int v,c;
};
int aqx,n,m;
ll f[N][N][(1<<N)+3],g[(1<<N)+3];
vector<nod> G[N+5];
vector<int> a[N][N];

int read() {
    int sss=0,www=1;
    char ccch=getchar();
    while(ccch<'0' || ccch>'9') { if(ccch=='-') www=-1; ccch=getchar(); }
    while(ccch>='0' && ccch<='9') sss=sss*10+ccch-'0',ccch=getchar();
    return sss*www;
}
void Add(ll &xcr, ll zzy) { xcr+=zzy,xcr=(xcr>mod?xcr-mod:xcr); }
int main()
{
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    //ios::sync_with_stdio(false);
    aqx=read();
    while(aqx--)
    {
    	for(int i=0; i<n; i++) G[i].clear();
    	for(int i=0; i<n; i++)
    		for(int j=0; j<n; j++) a[i][j].clear();

    	n=read(),m=read();
    	for(int i=1,x,y,z; i<=m; i++)
    	{
    		x=read()-1,y=read()-1,z=read();
    		if(x==y) continue;
    		G[x].pb((nod){y,z});
    		G[y].pb((nod){x,z});
    		a[x][y].pb(z);
    		a[y][x].pb(z);
    	}
    	for(int i=0; i<n; i++)
    		for(int j=0; j<n; j++)
    			sort(a[i][j].begin(),a[i][j].end());

    	memset(f,0x3f,sizeof(f));
    	for(int i=0; i<n; i++) f[i][i][(1<<i)]=0;
    	for(int s=0,ed=(1<<n)-1; s<=ed; s++)
    		for(int i=0; i<n; i++)
    			if((s>>i)&1)
    				for(int j=0,k; j<n; j++)
    					if(((s>>j)&1) && f[i][j][s]<INF)
    						for(auto tk:G[j])
    						{
    							k=tk.v;
    							if(((s>>k)&1)) continue;
    							f[i][k][s|(1<<k)]=min(f[i][k][s|(1<<k)],f[i][j][s]+tk.c);
    						}

    	memset(g,0x3f,sizeof(g));
    	
    	for(int i=0; i<n; i++)
    		for(int j=0; j<n; j++)
    			if((int)a[i][j].size()>1)
    				g[(1<<i)|(1<<j)]=a[i][j][0]+a[i][j][1];
    	
    	for(int i=0; i<n; i++)
    		for(auto j:G[i])
    			for(int s=0,ed=(1<<n); s<ed; s++)
    				if(((s>>i)&1) && ((s>>j.v)&1) && (s^(1<<i)^(1<<j.v))>0)
    					g[s]=min(g[s],f[i][j.v][s]+j.c);
    	for(int s=0,ed=(1<<n)-1; s<=ed; s++)
    	{
    		int t=(ed^s);
    		for(int i=0; i<n; i++)
    			if((s>>i)&1)
    				for(int j=0; j<n; j++)
    					if((s>>j)&1)
    						for(int ss=t; ss; ss=(t&(ss-1)))
    							g[s^ss]=min(g[s^ss],g[s]+f[i][j][ss^(1<<i)^(1<<j)]);
    	}

    	if(g[(1<<n)-1]==INF) puts("impossible");
    	else printf("%lld\n", g[(1<<n)-1]);
    }
    
    return 0;
}
2023/7/17 14:49
加载中...