当前位置: 首页 > news >正文

bzoj2595: [Wc2008]游览计划

斯坦纳树

f[i][zt]表示以i为根,连成的联通块包括那些景点

两个转移:f[i][zt]=f[i][tzt]+f[i][zt^tzt]-a[i]

      f[i][zt]=f[j][zt]+a[i] ((i,j)相邻)

后面这个可以用spfa优化

记得先进行前一个转移,还有容斥减掉a[i]

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>

#define P(x,y) m*(x-1)+y
using namespace std;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};

int c[110];
int cnt,f[110][2100],fr[110][2100];

struct node
{
    int x,y,next;
}a[410];int len,last[110];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int head,tail,list[110]; bool v[110];
void add(int &x){x++;if(x==105)x=1;}
void spfa(int zt)
{
    while(head!=tail)
    {
        int x=list[head];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(f[y][zt]>f[x][zt]+c[y])
            {
                f[y][zt]=f[x][zt]+c[y];
                fr[y][zt]=-x;
                if(v[y]==false)
                {
                    v[y]=true;
                    list[tail]=y;
                    add(tail);
                }
            }
        }
        v[x]=false;
        add(head);
    }
}

char ss[110];
void dfs(int x,int zt)
{
    if(ss[x]!='x')ss[x]='o';
    if(fr[x][zt]>0)
        dfs(x,fr[x][zt]),dfs(x,zt^fr[x][zt]);
    else if(fr[x][zt]<0)
        dfs(-fr[x][zt],zt);
}

int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    int n,m;
    scanf("%d%d",&n,&m);
    len=0;memset(last,0,sizeof(last));
    memset(f,63,sizeof(f));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&c[P(i,j)]);
            if(c[P(i,j)]==0)cnt++,f[P(i,j)][1<<(cnt-1)]=0;            
            for(int k=0;k<=3;k++)
            {
                int x=dx[k]+i,y=dy[k]+j;
                if(1<=x&&x<=n&&1<=y&&y<=m)
                    ins(P(i,j),P(x,y));
            }
        }
        
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~init~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    int li=(1<<cnt)-1; head=1,tail=1;
    for(int zt=1;zt<=li;zt++)
    {
        for(int i=1;i<=n*m;i++)
            for(int tzt=((zt-1)&zt);tzt!=0;tzt=((tzt-1)&zt))
                if(f[i][zt]>f[i][tzt]+f[i][zt^tzt]-c[i])
                {
                    f[i][zt]=min(f[i][zt],f[i][tzt]+f[i][zt^tzt]-c[i]);
                    fr[i][zt]=tzt;
                }
                
        memset(v,false,sizeof(v));
        for(int i=1;i<=n*m;i++)
            if(f[i][zt]!=f[0][0])
            {
                v[i]=true;
                list[tail]=i,add(tail);
            }
        spfa(zt);
    }
    
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~DP~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    int mmin=f[0][0],id;
    for(int i=1;i<=n*m;i++)
        if(f[i][li]<mmin)mmin=f[i][li],id=i;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(c[P(i,j)]==0)ss[P(i,j)]='x';
            else ss[P(i,j)]='_';
    dfs(id,li);
    printf("%d\n",mmin);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            printf("%c",ss[P(i,j)]);
        printf("\n");
    }
    
    //~~~~~~~~~~~~~~~~~~~~~~~~~print~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    return 0;
}

 

转载于:https://www.cnblogs.com/AKCqhzdy/p/10169194.html

相关文章:

  • C# 很少人知道的科技
  • asp.net——公共帮助类
  • 什么是二次开发
  • C++ 解析json串
  • 系统管理员需知的 16 个 iptables 使用技巧
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • 《HelloGitHub》第 33 期
  • grep-学习记录
  • 面试题30:包含 min 函数的栈
  • intellij中导入java包
  • Java模仿http请求工具类
  • 数据结构之链表 给定一个链表,判断链表中是否有环。
  • 有点颓废
  • JS判断单、多张图片加载完成
  • webfont在vue中的使用
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Angular4 模板式表单用法以及验证
  • canvas绘制圆角头像
  • ES6系统学习----从Apollo Client看解构赋值
  • Intervention/image 图片处理扩展包的安装和使用
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • NSTimer学习笔记
  • Octave 入门
  • Travix是如何部署应用程序到Kubernetes上的
  • Vim Clutch | 面向脚踏板编程……
  • 第十八天-企业应用架构模式-基本模式
  • 工程优化暨babel升级小记
  • 关于springcloud Gateway中的限流
  • 码农张的Bug人生 - 初来乍到
  • 前嗅ForeSpider教程:创建模板
  • 使用parted解决大于2T的磁盘分区
  • 通过几道题目学习二叉搜索树
  • 为视图添加丝滑的水波纹
  • 小程序测试方案初探
  • 怎样选择前端框架
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​一些不规范的GTID使用场景
  • %@ page import=%的用法
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (3)(3.5) 遥测无线电区域条例
  • (done) 两个矩阵 “相似” 是什么意思?
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (二十四)Flask之flask-session组件
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (三)c52学习之旅-点亮LED灯
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (转)EOS中账户、钱包和密钥的关系
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .NET 表达式计算:Expression Evaluator
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .net通用权限框架B/S (三)--MODEL层(2)
  • .NET学习教程二——.net基础定义+VS常用设置
  • :not(:first-child)和:not(:last-child)的用法