• luoguP4294 [WC2008]游览计划 斯坦纳树


    这个其实就是状压DP+spfa.    

    本题需要输出方案,有一点点麻烦 

    code:   

    #include <bits/stdc++.h>     
    #define ll long long 
    #define N 12     
    #define inf 0x3f3f3f3f
    #define setIO(s) freopen(s".in","r",stdin)  
    using namespace std;      
    int dx[]={0,-1,0,1};   
    int dy[]={-1,0,1,0};          
    int n,m,K=0,tot;    
    int val[N][N];   
    int bin[N],f[N*N][1<<N],id[N][N],X[N*N],Y[N*N],v[N*N],inq[N*N];              
    struct node 
    {
        int pos,s;   
        node(int pos=0,int s=0):pos(pos),s(s){}  
    }pre[N*N][1<<N];        
    queue<int>q;      
    void solve(int cur) 
    {
        while(!q.empty()) 
        {
            int u=q.front(); 
            q.pop(),inq[u]=0;   
            int x=X[u],y=Y[u];    
            for(int i=0;i<4;++i) 
            {
                int xx=x+dx[i]; 
                int yy=y+dy[i]; 
                if(!(xx>=1&&xx<=n&&yy>=1&&yy<=m)) 
                    continue;      
                int to=id[xx][yy];    
                if(f[to][cur]>f[u][cur]+v[to]) 
                {
                    f[to][cur]=f[u][cur]+v[to];        
                    pre[to][cur]=node(u,cur);      
                    if(!inq[to]) 
                    {
                        inq[to]=1;     
                        q.push(to);     
                    }
                }
            }
        }
    }     
    int mk[N][N];   
    void dfs(int x,int now) 
    {    
        mk[X[x]][Y[x]]=1;    
        if(!pre[x][now].pos)   
            return;     
        if(pre[x][now].pos==x)   
            dfs(x,now^pre[x][now].s);    
        dfs(pre[x][now].pos,pre[x][now].s);   
    }
    int main() 
    { 
        // setIO("input");     
        int i,j,rr=0;     
        scanf("%d%d",&n,&m);   
        for(i=1;i<N;++i)  
            bin[i]=1<<(i-1);     
        for(i=1;i<=n;++i)   
            for(j=1;j<=m;++j)  
                id[i][j]=++tot,X[id[i][j]]=i,Y[id[i][j]]=j;     
        memset(f,0x3f,sizeof(f));      
        for(i=1;i<=n;++i)   
            for(j=1;j<=m;++j)   
            {
                scanf("%d",&val[i][j]);      
                v[id[i][j]]=val[i][j];  
                if(!val[i][j])    
                {
                    ++K;      
                    rr=id[i][j];                  
                    f[id[i][j]][bin[K]]=0;  
                }    
            }
        for(i=1;i<bin[K+1];++i) 
        {                       
            for(int pos=1;pos<=tot;++pos)     
            {
                for(j=i&(i-1);j;j=i&(j-1)) 
                {
                    if(f[pos][j]+f[pos][i^j]-v[pos]<f[pos][i]) 
                    {  
                        f[pos][i]=f[pos][j]+f[pos][i^j]-v[pos];    
                        pre[pos][i]=node(pos,j);         
                    }   
                }      
                if(f[pos][i]<inf)   
                {     
                    inq[pos]=1;   
                    q.push(pos);    
                }
            }         
            solve(i);    
        }
        printf("%d
    ",f[rr][bin[K+1]-1]); 
        dfs(rr,bin[K+1]-1);   
        for(i=1;i<=n;++i) 
        {
            for(j=1;j<=m;++j)   
            {
                if(!val[i][j])   
                { 
                    printf("x");     
                }
                else 
                { 
                    if(mk[i][j])   printf("o");       
                    else printf("_"); 
    
                }
            }
            printf("
    "); 
        }      
        return 0;
    }
    

      

  • 相关阅读:
    java基础练习 4
    java基础练习 5
    java基础练习 3
    java基础练习 2
    二级联动菜单动态刷新下拉列表的一种实现方法
    疯狂Java讲义笔记(二)
    Windows10 Internet Explorer已停止工作的解决方法
    Git笔记
    Spring Boot笔记
    maven笔记
  • 原文地址:https://www.cnblogs.com/guangheli/p/12482114.html
Copyright © 2020-2023  润新知