zoukankan      html  css  js  c++  java
  • 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
    ",mmin);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
                printf("%c",ss[P(i,j)]);
            printf("
    ");
        }
        
        //~~~~~~~~~~~~~~~~~~~~~~~~~print~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        return 0;
    }
  • 相关阅读:
    Android百度地图
    Android开发性能优化大总结
    解析Android开发优化之:从代码角度进行优化的技巧
    073 HBASE的读写以及client API
    072 HBase的架构以及各个模块的功能
    071 HBase的安装部署以及简单使用
    070 关于HBase的概述
    069 Hue协作框架
    068 Oozie任务调度框架
    集合的知识点梳理(List,Set,不包含泛型)
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10169194.html
Copyright © 2011-2022 走看看