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

    首先有一个性质,一个双联通图一定可以拆成一个小的双联通子图和一条链

    一个点可以视为权值为0的双联通图或者一个点的链

    状压DP,枚举子集

    O(3^n*n^2)

    #include<cstdio>
    #include<algorithm>
    #define rep(i,x,y) for (int i=x; i<y; i++)
    using namespace std;
    int cnt,M[1005][1005],H[5005][15][15],last[15],G[5005][15][2],F[5005];
    struct node{
    	int to,next,val;
    }e[1000005];
    void add(int a,int b,int c){
    	e[++cnt].to=b;
    	e[cnt].next=last[a];
    	e[cnt].val=c;
    	last[a]=cnt;
    }
    int main(){
    	int T;
    	scanf("%d",&T);
    	while (T--){
    		int n,m;
    		scanf("%d%d",&n,&m);
    		cnt=0;
    		for (int i=0; i<n; i++) last[i]=0;
    		rep(i,0,n) rep(j,0,n) M[i][j]=1e9;
    		for (int i=1; i<=m; i++){
    			int x,y,z;
    			scanf("%d%d%d",&x,&y,&z);
    			x--,y--;
    			add(x,y,z);
    			add(y,x,z);
    			M[x][y]=min(M[x][y],z);
    			M[y][x]=min(M[y][x],z);
    		}
    		int Max=(1<<n);
    
    		rep(i,0,Max) rep(x,0,n) rep(y,0,n) H[i][x][y]=1e9;
    
    		for (int i=0; i<n; i++) H[1<<i][i][i]=0;
    
    		for (int i=0; i<Max; i++)
    			for (int S=0; S<n; S++)
    				for (int T=0; T<n; T++)
    					if (H[i][S][T]!=1e9){
    						for (int To=0; To<n; To++){
    							if (i&(1<<To)) continue;
    							H[i|(1<<To)][S][To]=min(H[i|(1<<To)][S][To],H[i][S][T]+M[To][T]);
    						}
    					}
    
    		rep(i,0,Max) rep(S,0,n) G[i][S][0]=G[i][S][1]=1e9;
    		for (int i=0; i<Max; i++)
    			for (int S=0; S<n; S++)
    				for (int j=last[S]; j; j=e[j].next){
    					int T=e[j].to;
    					if (i&(1<<T)){
    						if (G[i][S][0]>=e[j].val){
    							G[i][S][1]=G[i][S][0];
    							G[i][S][0]=e[j].val;
    						}
    						else if (G[i][S][1]>e[j].val) G[i][S][1]=e[j].val;
    					}
    				}
    		
    		rep(i,0,Max) F[i]=1e9;
    		
    		for (int i=0; i<n; i++) F[1<<i]=0;
    		for (int i=0; i<Max; i++)
    			for (int pre=(i-1)&i; pre; pre=(pre-1)&i){
    				int now=i-pre;
    				for (int S=0; S<n; S++)
    					for (int T=0; T<n; T++){
    						if (now&(1<<S) && now&(1<<T)){
    							int Sum=H[now][S][T]+G[pre][S][0];
    							if (Sum>=1e9) continue;
    							if (S!=T) Sum+=G[pre][T][0];
    							else Sum+=G[pre][T][1];
    							F[i]=min(F[i],F[pre]+Sum);
    						}
    					}
    			}
    		if (F[Max-1]==1e9) printf("impossible
    ");
    		else printf("%d
    ",F[Max-1]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    tensorflow中的name_scope, variable_scope
    tf.data.Dataset类的用法
    tensorflow错误:Shape (10, ?) must have rank at least 3
    最大似然估计、最大后验估计、贝叶斯估计的对比
    自然语言处理简述
    深度学习之GRU网络
    深度学习之Batch Normalization
    自然语言处理之序列标注问题
    Ubuntu安装jdk
    TypeScript 高级类型
  • 原文地址:https://www.cnblogs.com/silenty/p/9858240.html
Copyright © 2011-2022 走看看