zoukankan      html  css  js  c++  java
  • BZOJ1401 : Hexagon

    这题显然是一个最小斯坦纳树的模型,直接上模板即可,就是正六边形比较恶心。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define rep(i,n) for(int i=0;i<n;i++)
    #define INF 0x3f3f3f3f
    using namespace std;
    const int N=1610,M=9610;
    typedef pair<int,int>P;
    int R,n,m,k=4,f[N][1<<4],st[N],all=1<<k,ans,g[N],to[M],nxt[M],cost[N],e,id[41][41];
    bool vis[N][1<<4];
    queue<int>Q;
    int read(){
      char ch;
      while(!(((ch=getchar())=='A')||(ch=='B')||(ch=='C')||(ch=='D')||(ch=='.')));
      return ch=='.'?4:ch-'A';
    }
    void add(int u,int v){to[e]=v;nxt[e]=g[u];g[u]=e++;}
    void add(int u,int x,int y){
      if(x<0||y<0||x>=m||y>=m)return;
      if(~id[x][y]&&id[x][y]!=u)add(u,id[x][y]);
    }
    void spfa(int S){
      while(!Q.empty()){
        int u=Q.front();Q.pop();
        vis[u][S]=false;
        for(int p=g[u];~p;p=nxt[p]){
          int v=to[p];
          int w=cost[v];
          if(f[v][st[v]|S]>f[u][S]+w){
            f[v][st[v]|S]=f[u][S]+w;
            if(st[v]|S!=S||vis[v][S])continue;
            vis[v][S]=1;
            Q.push(v);
          }
        }
      }
    }
    void solve(){
      memset(g,-1,sizeof g);
      while(!Q.empty())Q.pop();
      e=0;n=k;m=R*2-1;
      rep(i,m)rep(j,m)id[i][j]=-1;
      rep(i,R-1)rep(j,R+i){
        int x=read();
        if(x<k)cost[id[i][j]=x]=0;else cost[id[i][j]=n++]=1;
      }
      rep(i,R)rep(j,m-i){
        int x=read();
        if(x<k)cost[id[R+i-1][j]=x]=0;else cost[id[R+i-1][j]=n++]=1;
      }
      rep(i,m)rep(j,m)if(~id[i][j]){
        add(id[i][j],i,j-1);
        add(id[i][j],i,j+1);
        if(i<R-1){
          add(id[i][j],i-1,j-1);
          add(id[i][j],i-1,j);
          add(id[i][j],i+1,j);
          add(id[i][j],i+1,j+1);
        }else if(i==R-1){
          add(id[i][j],i-1,j-1);
          add(id[i][j],i-1,j);
          add(id[i][j],i+1,j-1);
          add(id[i][j],i+1,j);
        }else{
          add(id[i][j],i-1,j);
          add(id[i][j],i-1,j+1);
          add(id[i][j],i+1,j-1);
          add(id[i][j],i+1,j);
        }
      }
      rep(i,n)rep(j,all)f[i][j]=INF;
      memset(st,0,sizeof st);
      memset(vis,0,sizeof vis);
      rep(i,k)st[i]=1<<i,f[i][st[i]]=0;
      for(int j=1;j<all;j++){
        rep(i,n){
          if(st[i]&&(st[i]&j)==0)continue;
          for(int sub=(j-1)&j;sub;sub=(sub-1)&j){
            int x=st[i]|sub,y=st[i]|(j-sub);
            f[i][j]=min(f[i][j],f[i][x]+f[i][y]-cost[i]);
          }
          if(f[i][j]<INF){
            Q.push(i);
            vis[i][j]=true;
          }
        }
        spfa(j);
      }
      ans=INF;
      rep(j,n)ans=min(ans,f[j][all-1]);
      printf("You have to buy %d parcels.
    ",ans);
    }
    int main(){
      while(scanf("%d",&R),R)solve();
      return 0;
    }
    

      

  • 相关阅读:
    Mysql学习(慕课学习笔记7)修改数据表(下)
    Mysql学习(慕课学习笔记1)启动、登录及常用命令
    Mysql学习(慕课学习笔记2)数据库的创建与删除
    手机测试体系讲解
    Android开发之旅:环境搭建
    免费搭建wordpress博客有感
    第一篇
    浅谈通信网络(二)——信号
    小dai浅谈通信网络(一)——引子
    投票调查系统数据库设计及大家指教
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403193.html
Copyright © 2011-2022 走看看