BZOJ 3590 [Snoi2013]Quare [状压DP]

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=44;
const int maxm=(1<<12)+1;
struct point
{
	int to;
	int nxt;
	int w;
}edge[maxn*2];
int T,n,m,tot;
int head[maxn];
int g[maxm][14][14],h1[14][maxm],h2[14][maxm];
int f[maxm],Log[maxm];

inline void add(int u,int v,int w)
{
	tot++;
	edge[tot].nxt=head[u];
	edge[tot].to=v;
	edge[tot].w=w;
	head[u]=tot;
}

inline int lowbit(int x)
{
	return x&-x;
}

inline void solve()
{
    int i,S,T,ta,tb,a,b,c;
	for(int i=0;i<n;i++) Log[1<<i]=i;
	int up=(1<<n)-1;
	for(int i=0;i<n;i++)
	{
		g[1<<i][i][i]=0;
		f[1<<i]=0;
	}
	for(int S=1;S<=up;S++)
		for(int i=up^S;i;i-=lowbit(i))
		{
			int a=Log[lowbit(i)];
			for(int j=head[a];j;j=edge[j].nxt)
			{
				int v=edge[j].to;
				if((1<<v)&S)
				{
					if(h1[a][S]>edge[j].w)
					{
						h2[a][S]=h1[a][S];
						h1[a][S]=edge[j].w;
					}
					else
						h2[a][S]=min(h2[a][S],edge[j].w);
				}
			}
		}
	for(int S=1;S<=up;S++)
	{
		for(int p1=S;p1;p1-=lowbit(p1))
		for(int p2=S;p2;p2-=lowbit(p2))
		{
			int a=Log[lowbit(p1)],b=Log[lowbit(p2)];
			if(a==b) continue;
			for(int i=head[a];i;i=edge[i].nxt)
			{
				int v=edge[i].to;
				if((1<<v)&S)
				g[S][a][b]=min(g[S][a][b],g[S^(1<<a)][v][b]+edge[i].w);
			}
		}
	}
	for(int S=1;S<=up;S++)
	{
		if(S==lowbit(S)) continue;
		for(int T=(S-1)&S;T;T=S&(T-1))
		{
			for(int p1=T;p1;p1-=lowbit(p1))
			for(int p2=T;p2;p2-=lowbit(p2))
			{
				int a=Log[lowbit(p1)],b=Log[lowbit(p2)];
				if(a==b)
					f[S]=min(f[S],f[S^T]+g[T][a][b]+h1[a][S^T]+h2[a][S^T]);
				else f[S]=min(f[S],f[S^T]+g[T][a][b]+h1[a][S^T]+h1[b][S^T]);
			}
		}
	}
	if(f[up]==0x0f0f0f0f) puts("impossible");
	else printf("%d\n",f[up]);
}

inline void init()
{
	tot=0;
	memset(head,0,sizeof(head));
	memset(f,0x0f,sizeof(f));
	memset(g,0x0f,sizeof(g));
	memset(h1,0x0f,sizeof(h1));
	memset(h2,0x0f,sizeof(h2));
}

int main()
{
	scanf("%d",&T);
	while(T--)
	{
		init();
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++)
		{
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			u--,v--;
			add(u,v,w),add(v,u,w);
		}
		solve();
	}
	return 0;
}
posted @ 2018-05-17 10:25  Captain_fcj  阅读(171)  评论(0编辑  收藏  举报