• Luogu P4294 [WC2008]游览计划


    斯坦纳树。

    (f[i][j][s]) 表示当前 ((i,j)) 覆盖关键点的状态为 (s) 的最小代价。

    (f[i][j][s]=min(f[i][j][s],f[i][j][s { m xor} t]+f[i][j][t]-a[i][j]))

    (f[i+{ m dx}][j+{ m dy}][s]=min(f[i+{ m dx}][j+{ m dy}][s],f[i][j][s]+a[i+{ m dx}][j+{ m dy}]))

    第一个式子直接DP;第二个式子在第一个式子DP完后跑一边spfa即可。

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
      register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
      do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
    } const int N=20,Inf=0x3f3f3f3f,dx[]={0,-1,0,1},dy[]={1,0,-1,0};
    int n,m,tot,sx,sy;
    int a[N][N],f[N][N][1<<11];
    bool vis[N][N],ans[N][N];
    struct node {int x,y,s;}lst[N][N][1<<11];
    struct pt {int x,y;};
    queue<pt> q;
    inline void spfa(int s) {
      while(q.size()) {
        R x=q.front().x,y=q.front().y; q.pop();
        vis[x][y]=false;
        for(R i=0;i<4;++i) {
          R xx=x+dx[i],yy=y+dy[i];
          if(xx<1||xx>n||yy<1||yy>m) continue;
          if(f[x][y][s]+a[xx][yy]<f[xx][yy][s]) {
            f[xx][yy][s]=f[x][y][s]+a[xx][yy];
            if(!vis[xx][yy]) 
              q.push((pt){xx,yy}),vis[xx][yy]=true;
            lst[xx][yy][s]=(node){x,y,s};
          }
        }
      }
    }
    inline void dfs(int x,int y,int s) {
      if(!lst[x][y][s].s) return ;
      ans[x][y]=1;
      R i=lst[x][y][s].x,j=lst[x][y][s].y,t=lst[x][y][s].s;
      dfs(i,j,t);
      if(i==x&&j==y) dfs(i,j,s^t);
    }
    inline void main() {
      n=g(),m=g(),tot=0;
      memset(f,0x3f,sizeof f);
      for(R i=1;i<=n;++i) for(R j=1;j<=m;++j) {
        a[i][j]=g();
        if(!a[i][j]) sx=i,sy=j,f[i][j][1<<tot]=0,++tot;
      }
      for(R s=1,lim=1<<tot;s<lim;++s) {
        while(q.size()) q.pop();
        for(R i=1;i<=n;++i) for(R j=1;j<=m;++j) {
          for(R t=s;t;t=s&(t-1)) 
            if(f[i][j][s]>f[i][j][t]+f[i][j][s^t]-a[i][j]) {
              f[i][j][s]=f[i][j][t]+f[i][j][s^t]-a[i][j];
              lst[i][j][s]=(node){i,j,t};
            }
          if(f[i][j][s]!=Inf) 
            q.push((pt){i,j}),vis[i][j]=true;
        }
        spfa(s);
      }
      printf("%d
    ",f[sx][sy][(1<<tot)-1]);
      dfs(sx,sy,(1<<tot)-1);
      for(R i=1;i<=n;++i,putchar(10)) for(R j=1;j<=m;++j) {
        if(!a[i][j]) {putchar('x'); continue;}
        putchar(ans[i][j]?'o':'_');
      } 
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2020.01.18

  • 相关阅读:
    通信原理
    java实现聊天室的简单实现
    计算机网络笔记——第四章、网络层
    泛型高级之通配符
    看文档总结
    HashSet源码解析
    HashTable源码解析
    计算机网络笔记——第三章、数据链路层
    Collection集合的功能
    第六章 应用层
  • 原文地址:https://www.cnblogs.com/Jackpei/p/12208534.html
Copyright © 2020-2023  润新知