zoukankan      html  css  js  c++  java
  • HDU1964 Pipes 插头DP

      题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1964

      空白区域之间有权值,求经过所有空白区域的哈密顿回路的最小权值。简单的插头DP,空白区域特殊处理即可。

      1 //STATUS:C++_AC_203MS_664KB
      2 #include<stdio.h>
      3 #include<stdlib.h>
      4 #include<string.h>
      5 #include<math.h>
      6 #include<iostream>
      7 #include<string>
      8 #include<algorithm>
      9 #include<vector>
     10 #include<queue>
     11 #include<stack>
     12 #include<map>
     13 using namespace std;
     14 #define LL long long
     15 #define pii pair<int,int>
     16 #define Max(a,b) ((a)>(b)?(a):(b))
     17 #define Min(a,b) ((a)<(b)?(a):(b))
     18 #define mem(a,b) memset(a,b,sizeof(a))
     19 #define lson l,mid,rt<<1
     20 #define rson mid+1,r,rt<<1|1
     21 const int N=21,INF=0x3f3f3f3f,MOD=40001,STA=8000010;
     22 const double DNF=1e13;
     23 
     24 int g[N][N],code[N],ma[N];
     25 int T,n,m,ex,ey;
     26 
     27 struct Hash{     //Hash表,MOD为表长,STA为表大小
     28     int first[MOD],next[STA],size;
     29     int f[STA];
     30     LL sta[STA];
     31     void init(){
     32         size=0;
     33         mem(first,-1);
     34     }
     35     void add(LL st,int ans){
     36         int i,u=st%MOD;
     37         for(i=first[u];i!=-1;i=next[i]){
     38             if(sta[i]==st){
     39                 f[i]=Min(f[i],ans);
     40                 return;
     41             }
     42         }
     43         sta[size]=st;
     44         f[size]=ans;
     45         next[size]=first[u];
     46         first[u]=size++;
     47     }
     48 }hs[2];
     49 
     50 void shift(int p)    //换行移位
     51 {
     52     int k;
     53     LL sta;
     54     for(k=0;k<hs[!p].size;k++){
     55         sta=hs[!p].sta[k]<<3;
     56         hs[p].add(sta,hs[!p].f[k]);
     57     }
     58 }
     59 
     60 LL getsta()   //最小表示法
     61 {
     62     LL i,cnt=1,sta=0;
     63     mem(ma,-1);
     64     ma[0]=0;
     65     for(i=0;i<=m;i++){
     66         if(ma[code[i]]==-1)ma[code[i]]=cnt++;
     67         code[i]=ma[code[i]];
     68         sta|=(LL)code[i]<<(3*i);
     69     }
     70     return sta;
     71 }
     72 
     73 void getcode(LL sta)
     74 {
     75     int i;
     76     for(i=0;i<=m;i++){
     77         code[i]=sta&7;
     78         sta>>=3;
     79     }
     80 }
     81 
     82 void unblock(int i,int j,int p)
     83 {
     84     int k,t;
     85     LL cnt,x,y;
     86     for(k=0;k<hs[!p].size;k++){
     87         getcode(hs[!p].sta[k]);
     88         x=code[j],y=code[j+1];
     89         cnt=hs[!p].f[k];
     90         if(x && y){     //合并连通分量
     91             code[j]=code[j+1]=0;
     92             if(x!=y){
     93                 for(t=0;t<=m;t++)
     94                     if(code[t]==y)code[t]=x;
     95                 hs[p].add(getsta(),cnt+(g[i][j]<10?g[i][j]:0));
     96             }
     97             else if(i==ex && j==ey){   //最后一个点特殊处理
     98                 hs[p].add(getsta(),cnt);
     99             }
    100         }
    101         else if(x&&!y || !x&&y){   //延续连通分量
    102             t=x?x:y;
    103             if(g[i+1][j]>=0){
    104                 code[j]=t;code[j+1]=0;
    105                 hs[p].add(getsta(),cnt+(g[i][j]<10?g[i][j]:0));
    106             }
    107             if(g[i][j+1]>=0){
    108                 code[j]=0;code[j+1]=t;
    109                 hs[p].add(getsta(),cnt+(g[i][j]<10?g[i][j]:0));
    110             }
    111         }
    112         else {  //创建新连通分量
    113             if(g[i][j]>=0 && g[i][j]<=9){
    114                 hs[p].add(getsta(),cnt);
    115             }
    116             if(g[i+1][j]>=0 && g[i][j+1]>=0){
    117                 code[j]=code[j+1]=8;
    118                 hs[p].add(getsta(),cnt);
    119             }
    120         }
    121     }
    122 }
    123 
    124 void block(LL j,int p)
    125 {
    126     int k;
    127     for(k=0;k<hs[!p].size;k++){
    128         getcode(hs[!p].sta[k]);
    129         if(code[j]==0 && code[j+1]==0)
    130             hs[p].add(getsta(),hs[!p].f[k]);
    131     }
    132 }
    133 
    134 int slove()
    135 {
    136     int i,j,p;
    137     hs[0].init();
    138     hs[p=1].init();
    139     hs[0].add(0,0);
    140     for(i=0;i<n;i++){
    141         for(j=0;j<m;j++){
    142             if(g[i][j]>=0)unblock(i,j,p);
    143             else p=!p;
    144             hs[p=!p].init();
    145         }
    146         shift(p);   //换行移位
    147         hs[p=!p].init();
    148     }
    149     for(i=0;i<hs[!p].size;i++)
    150         if(hs[!p].sta[i]==0)return hs[!p].f[i];
    151     return 0;
    152 }
    153 
    154 int main()
    155 {
    156  //   freopen("in.txt","r",stdin);
    157     int i,j,ans;
    158     char s[N];
    159     scanf("%d",&T);
    160     while(T--)
    161     {
    162         scanf("%d%d",&n,&m);
    163         mem(g,-1);
    164         n=n*2-1;
    165         m=m*2-1;
    166         scanf("%s",s);
    167         getchar();
    168         for(i=0;i<n;i++){
    169             gets(s);
    170             for(j=1;j<=m;j++){
    171                 if(s[j]==' ')g[i][j-1]=10;
    172                 else if(s[j]=='#')g[i][j-1]=-1;
    173                 else g[i][j-1]=s[j]-'0';
    174             }
    175         }
    176         scanf("%s",s);
    177         ex=n-1,ey=m-1;
    178 
    179         ans=slove();
    180 
    181         printf("%d\n",ans);
    182     }
    183     return 0;
    184 }
  • 相关阅读:
    [转载]我的PMP复习备考经验谈(下篇)——一本关于PMP备考的小指南
    安装MongoDB遇到问题
    安装MongoDB遇到问题
    (热死你)Resin https ssl Linux 配置,实战可用
    高性能web服务器(热死你)Resin Linux的安装、配置、部署,性能远超Nginx支持Java、PHP等
    我最近用Python写了一个算法,不需要写任何规则就能自动识别一个网页的内容
    20161230实时量化监控,成效显著,实在忍不住要给大家秀一把
    16年收官之战,堪称完美,祝愿大家2017一举成名天下闻,虎啸龙吟展宏图
    我3年前开发的IM即时通讯一直没勇气推出,现在智能时代了,有什么可以结合的地方吗?
    忙活了一周时间,开发了一个年会抽奖系统,免费开放给大家(含操作视频及下载地址)
  • 原文地址:https://www.cnblogs.com/zhsl/p/3003852.html
Copyright © 2011-2022 走看看