zoukankan      html  css  js  c++  java
  • #斯坦纳树#洛谷 4294 [WC2008]游览计划

    题目


    分析

    几乎就是模板题,考虑不同点就是它是点权,
    所以在求两个子集的时候要减去这个点的点权,
    还有一点恶心的就是要输出方案,令人作呕


    代码

    #include <cstdio>
    #include <cctype>
    #include <queue>
    #include <cstring>
    #define rr register
    using namespace std;
    const int N=101,M=1051; queue<int>q;
    struct node{int y,w,next;}e[M<<2]; pair<int,int>pre[M][N];
    int dp[M][N],v[N],two[11],p[N],as[N],a[N],n,m,al,k=1,tot;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline signed rk(int x,int y){return (x-1)*m+y;}
    inline void add(int x,int y,int w){e[++k]=(node){y,w,as[x]},as[x]=k;}
    inline void Spfa(int z){
    	while (q.size()){
    		rr int x=q.front(); q.pop();
    		for (rr int i=as[x];i;i=e[i].next)
    		if (dp[z][e[i].y]>dp[z][x]+e[i].w){
    			dp[z][e[i].y]=dp[z][x]+e[i].w;
    			pre[z][e[i].y]=make_pair(z,x);
    			if (!v[e[i].y]) v[e[i].y]=1,q.push(e[i].y);
    		}
    		v[x]=0;
    	}
    }
    inline void dfs(int S,int now){
    	if (!pre[S][now].first) return;
    	v[now]=1;
    	if (pre[S][now].second==now)
    	    dfs(pre[S][now].first^S,now);
    	dfs(pre[S][now].first,pre[S][now].second);
    }
    signed main(){
    	memset(dp,0x3f,sizeof(dp));
    	n=iut(),m=iut(),tot=n*m,two[0]=1;
    	for (rr int i=1;i<11;++i) two[i]=two[i-1]<<1;
    	for (rr int i=1;i<=n;++i)
    	for (rr int j=1,RK;j<=m;++j){
    	    RK=rk(i,j),a[RK]=iut();
    	    if (!a[RK]) p[al++]=RK;
    	    if (j>1) add(RK,rk(i,j-1),a[rk(i,j-1)]),add(rk(i,j-1),RK,a[RK]);
    	    if (i>1) add(RK,rk(i-1,j),a[rk(i-1,j)]),add(rk(i-1,j),RK,a[RK]);
    	}
    	for (rr int i=0;i<al;++i) dp[two[i]][p[i]]=0;
    	for (rr int S=0;S<two[al];++S){
    		memset(v,0,sizeof(v));
    		for (rr int i=1;i<=tot;++i){
    			for (rr int j=S&(S-1);j;j=(j-1)&S)
    			if (dp[S][i]>dp[j][i]+dp[S^j][i]-a[i]){
    				dp[S][i]=dp[j][i]+dp[S^j][i]-a[i];
    				pre[S][i]=make_pair(j,i);
    			}
    			if (dp[S][i]^dp[0][0]) q.push(i),v[i]=1;
    		}
    		Spfa(S);
    	}
    	printf("%d",dp[two[al]-1][p[0]]);
    	dfs(two[al]-1,p[0]);
    	for (rr int i=1,tot=0;i<=n;++i){
    	    putchar(10);
    		for (rr int j=1;j<=m;++j)
    		if (rk(i,j)==p[tot]) ++tot,putchar('x');
    		    else if (v[rk(i,j)]) putchar('o');
    		        else putchar('_');
    	}
    	return 0;
    }
    
  • 相关阅读:
    学习Swift -- 构造器(上)
    学习Swift -- 继承
    学习Swift -- 数组(Array)
    学习Swift--下标脚本
    学习Swift--方法
    学习Swift--属性
    Swift 类和结构体的简单认识
    dedecms代码研究二
    dedecms代码研究一
    PHP isset()与empty()的区别
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13921155.html
Copyright © 2011-2022 走看看