zoukankan      html  css  js  c++  java
  • Ural 1519 Formula 1 插头DP(单回路)

      题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1519

       一条哈密顿回路路,反正是写到蛋疼了,不过终于解决了,插头DP这玩意,太容易出错了,要注意block的处理。

      1 //STATUS:C++_AC_343MS_961KB
      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=15,INF=0x3f3f3f3f,MOD=4001,STA=1000010;
     22 const double DNF=100000000000;
     23 
     24 int g[N][N],code[N],ma[N];
     25 int n,m,ex,ey;
     26 
     27 struct Hash{
     28     int first[MOD],next[STA],size;
     29     LL f[STA],sta[STA];
     30     void init(){
     31         size=0;
     32         mem(first,-1);
     33     }
     34     void add(LL st,LL ans){
     35         int i,u=st%MOD;
     36         for(i=first[u];i!=-1;i=next[i]){
     37             if(sta[i]==st){
     38                 f[i]+=ans;
     39                 return;
     40             }
     41         }
     42         sta[size]=st;
     43         f[size]=ans;
     44         next[size]=first[u];
     45         first[u]=size++;
     46     }
     47 }hs[2];
     48 
     49 void shift(int p)    //换行移位
     50 {
     51     int k;
     52     LL sta;
     53     for(k=0;k<hs[!p].size;k++){
     54         sta=hs[!p].sta[k]<<3;
     55         hs[p].add(sta,hs[!p].f[k]);
     56     }
     57 }
     58 
     59 LL getsta()    //最小表示法
     60 {
     61     LL i,cnt=1,sta=0;
     62     mem(ma,-1);
     63     ma[0]=0;
     64     for(i=0;i<=m;i++){
     65         if(ma[code[i]]==-1)ma[code[i]]=cnt++;
     66         code[i]=ma[code[i]];
     67         sta|=(LL)code[i]<<(3*i);
     68     }
     69     return sta;
     70 }
     71 
     72 void getcode(LL sta)
     73 {
     74     int i;
     75     for(i=0;i<=m;i++){
     76         code[i]=sta&7;
     77         sta>>=3;
     78     }
     79 }
     80 
     81 void unblock(int i,int j,int p)
     82 {
     83     int k,t;
     84     LL cnt,x,y;
     85     for(k=0;k<hs[!p].size;k++){
     86         getcode(hs[!p].sta[k]);
     87         x=code[j],y=code[j+1];
     88         cnt=hs[!p].f[k];
     89         if(x && y){          //合并连通分量
     90             code[j]=code[j+1]=0;
     91             if(x!=y){
     92                 for(t=0;t<=m;t++)
     93                     if(code[t]==y)code[t]=x;
     94                 hs[p].add(getsta(),cnt);
     95             }
     96             else if(i==ex && j==ey){     //最后一个点特殊处理
     97                 hs[p].add(getsta(),cnt);
     98             }
     99         }
    100 
    101         else if(x&&!y || !x&&y){    //延续连通分量
    102             t=x?x:y;
    103             if(g[i+1][j]){
    104                 code[j]=t;code[j+1]=0;
    105                 hs[p].add(getsta(),cnt);
    106             }
    107             if(g[i][j+1]){
    108                 code[j]=0;code[j+1]=t;
    109                 hs[p].add(getsta(),cnt);
    110             }
    111         }
    112         else if(g[i+1][j] && g[i][j+1]){   //创建新连通分量
    113             code[j]=code[j+1]=8;
    114             hs[p].add(getsta(),cnt);
    115         }
    116     }
    117 }
    118 
    119 void block(LL j,int p)
    120 {
    121     int k;
    122     for(k=0;k<hs[!p].size;k++){
    123         getcode(hs[!p].sta[k]);
    124         code[j]=code[j+1]=0;
    125         hs[p].add(getsta(),hs[!p].f[k]);
    126     }
    127 }
    128 
    129 LL slove()
    130 {
    131     int i,j,p;
    132     hs[0].init();
    133     hs[p=1].init();
    134     hs[0].add(0,1);
    135     for(i=0;i<n;i++){
    136         for(j=0;j<m;j++){
    137             if(g[i][j])unblock(i,j,p);
    138             else block(j,p);    //p=!p优化
    139             hs[p=!p].init();
    140         }
    141         shift(p);   //换行移位
    142         hs[p=!p].init();
    143     }
    144     for(i=0;i<hs[!p].size;i++){
    145         if(hs[!p].sta[i]==0)return hs[!p].f[i];
    146     }
    147 
    148     return 0;
    149 }
    150 
    151 int main()
    152 {
    153  //   freopen("in.txt","r",stdin);
    154     int i,j;
    155     LL ans;
    156     char c;
    157     while(~scanf("%d%d",&n,&m) && (n || m))
    158     {
    159         mem(g,0);
    160         ex=-1;
    161         for(i=0;i<n;i++){
    162             for(j=0;j<m;j++){
    163                 scanf(" %c",&c);
    164                 g[i][j]=(c=='.');
    165                 if(g[i][j])ex=i,ey=j;
    166             }
    167         }
    168         if(ex==-1)ans=0;
    169         else ans=slove();
    170 
    171         printf("%I64d\n",ans);
    172     }
    173     return 0;
    174 }
  • 相关阅读:
    Keras安装
    sql根据查询顺序返回结果
    @Configuration @Bean
    SQL高级优化系列
    数据结构与算法系列(二)-- 算法
    数据结构与算法系列(一)-- 数据结构
    Golang中Label的用法
    日志收集系统系列(五)之LogTransfer
    日志收集系统系列(四)之LogAgent优化
    日志收集系统系列(三)之LogAgent
  • 原文地址:https://www.cnblogs.com/zhsl/p/2992648.html
Copyright © 2011-2022 走看看