zoukankan      html  css  js  c++  java
  • bzoj3590: [Snoi2013]Quare

    传送门

    impossible打错结果WA了半个小时我觉得自己也是挺强的……
    顺便发现我模拟赛的时候从来没有打对过任何一道dp……
    果然dp就是智商的分水岭啊QAQ
    首先最优解肯定是若干个环套在一起,或者说一个强连通分量加上一条链可以组成一个更大的强联通分量。
    我们分别记录一下状态,(h1[u][S])表示点(u)(S)的点集中的随便哪个点的最小距离,(h2[u][S])表示次小距离
    (g[u][v][S])表示一条链,其中链的两端为(u,v),链上的点为(S)的最小花费
    (f[S])表示(S)中的点组成强联通分量时的最小花费
    然后用强联通分量组成更大的强联通分量即可
    代码抄袭CQzhangyu的

    //minamoto
    #include<bits/stdc++.h>
    #define rint register int
    #define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
    #define go(u) for(register int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    using namespace std;
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    const int N=105,M=(1<<12)+5;
    int n,m,lim,T,u,v,vva,w,tot;
    struct eg{int v,nx,w;}e[N];int head[N],val[N],Log[M],h1[15][M],h2[15][M],g[15][15][M],f[M];
    inline void add(int u,int v,int w){e[++tot]={v,head[u],w},head[u]=tot;}
    void solve(){
    	scanf("%d%d",&n,&m),lim=(1<<n)-1;
    	memset(head,0,sizeof(head)),tot=0;
    	fp(i,0,m-1)scanf("%d%d%d",&u,&v,&w),add(u-1,v-1,w),add(v-1,u-1,w);
    	fp(i,0,n-1)Log[1<<i]=i;
    	memset(h1,0x0f,sizeof(h1)),memset(h2,0x0f,sizeof(h2)),memset(g,0x0f,sizeof(g)),memset(f,0x0f,sizeof(f));
    	fp(S,0,lim)for(rint ta=lim^S;ta;ta-=ta&-ta){
    		u=Log[ta&-ta];go(u)if(S&(1<<v)){
    			if(e[i].w<h1[u][S])h2[u][S]=h1[u][S],h1[u][S]=e[i].w;
    			else cmin(h2[u][S],e[i].w);
    		}
    	}
    	fp(i,0,n-1)g[i][i][1<<i]=f[1<<i]=0;
    	fp(S,1,lim)for(rint ta=S;ta;ta-=ta&-ta)for(rint tb=S;tb;tb-=tb&-tb){
    		u=Log[ta&-ta],vva=Log[tb&-tb];if(u==vva)continue;
    		go(vva)if(S&(1<<v))cmin(g[u][vva][S],g[u][v][S^(1<<vva)]+e[i].w);
    	}
    	fp(S,1,lim){
    		if(S==(S&-S))continue;
    		for(rint T=(S-1)&S;T;T=(T-1)&S)for(rint ta=T;ta;ta-=ta&-ta)for(rint tb=T;tb;tb-=tb&-tb){
    			u=Log[ta&-ta],vva=Log[tb&-tb];
    			if(u==vva)cmin(f[S],f[S^T]+g[u][vva][T]+h1[u][S^T]+h2[u][S^T]);
    			else cmin(f[S],f[S^T]+g[u][vva][T]+h1[u][S^T]+h1[vva][S^T]);
    		}
    	}
    	if(f[lim]==0x0f0f0f0f)puts("impossible");
    	else printf("%d
    ",f[lim]);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d",&T);
    	while(T--)solve();
    	return 0;
    }
    
  • 相关阅读:
    Spring Boot 定时+多线程执行
    Spring Boot + Vue Element实现Excel文件上传、解析、下载(含完整实现过程)
    立个flag,2020年比2019年产出提升10倍
    《Google工作法》读书笔记
    学习Go语言(二)快速入门
    学习Go语言(一)环境安装及HelloWorld
    WPF 自定义控件缩放
    上、下位机软件通信时,结构体的内存对齐问题
    C 语言能不能在头文件定义全局变量?
    注释格式
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10017800.html
Copyright © 2011-2022 走看看