• POJ1739 Tony's Tour 插头DP(单条路径)


      题目链接:http://poj.org/problem?id=1739

      完全可以用Ural 1519 Formula 1 插头DP(单回路)的代码解决此题,只要把图修改一下: 

         ....           ........
         ....    ->     .######.
         ....           .#....#.
    .#....#.
    .#....#.
    ........ 

    当然也可以在起点和终点独立处理插头。

    修改建图:
    View Code
      1 //STATUS:C++_AC_94MS_232KB
      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{     //Hash表,MOD为表长,STA为表大小
     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);
    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     return 0;
    147 }
    148 
    149 int main()
    150 {
    151  //   freopen("in.txt","r",stdin);
    152     int i,j;
    153     LL ans;
    154     char c;
    155     while(~scanf("%d%d",&n,&m) && (n || m))
    156     {
    157         mem(g,0);
    158         n+=2;m+=4;
    159         for(i=0;i<m;i++)g[0][i]=1;
    160         for(i=0;i<n;i++)g[i][0]=g[i][m-1]=1;
    161         g[n-1][1]=g[n-1][m-2]=1;
    162         ex=n-1,ey=m-1;
    163         for(i=2;i<n;i++){
    164             for(j=2;j<m-2;j++){
    165                 scanf(" %c",&c);
    166                 g[i][j]=(c=='.');
    167             }
    168         }
    169         ans=slove();
    170 
    171         printf("%I64d\n",ans);
    172     }
    173     return 0;
    174 }

      建立独立插头:

    View Code
      1 //STATUS:C++_AC_63MS_232KB
      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,sx,sy,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             if(x==y)continue;
     91             code[j]=code[j+1]=0;
     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((x&&!y) || (!x&&y)){
     97             if((i==sx && j==sy) || (i==ex && j==ey)){
     98                 code[j]=code[j+1]=0;
     99                 hs[p].add(getsta(),cnt);
    100             }
    101             else {
    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         }
    113         else{
    114             if(i==sx && j==sy){
    115                if(g[i][j+1]){
    116                     code[j+1]=8;
    117                     hs[p].add(getsta(),cnt);
    118                 }
    119             }
    120             else if(g[i+1][j] && g[i][j+1]){
    121                 code[j]=code[j+1]=8;
    122                 hs[p].add(getsta(),cnt);
    123             }
    124         }
    125     }
    126 }
    127 
    128 void block(LL j,int p)
    129 {
    130     int k;
    131     for(k=0;k<hs[!p].size;k++){
    132         getcode(hs[!p].sta[k]);
    133         code[j]=code[j+1]=0;
    134         hs[p].add(getsta(),hs[!p].f[k]);
    135     }
    136 }
    137 
    138 LL slove()
    139 {
    140     int i,j,p;
    141     hs[0].init();
    142     hs[p=1].init();
    143     hs[0].add(0,1);
    144     for(i=0;i<n;i++){
    145         for(j=0;j<m;j++){
    146             if(g[i][j])unblock(i,j,p);
    147             else block(j,p);
    148             hs[p=!p].init();
    149         }
    150         shift(p);
    151         hs[p=!p].init();
    152     }
    153     for(i=0;i<hs[!p].size;i++ )
    154         if(hs[!p].sta[i]==0)return hs[!p].f[i];
    155     return 0;
    156 }
    157 
    158 int main()
    159 {
    160  //   freopen("in.txt","r",stdin);
    161     int i,j;
    162     LL ans;
    163     char c;
    164     while(~scanf("%d%d",&n,&m) && (n || m))
    165     {
    166         mem(g,0);
    167         sx=n-1,sy=0;
    168         ex=n-1,ey=m-1;
    169         for(i=0;i<n;i++){
    170             for(j=0;j<m;j++){
    171                 scanf(" %c",&c);
    172                 g[i][j]=(c=='.');
    173             }
    174         }
    175 
    176         if(g[sx][sy]==0 || g[ex][ey]==0)ans=0;
    177         else if(n==m && n==1)ans=1;
    178         else ans=slove();
    179 
    180         printf("%I64d\n",ans);
    181     }
    182     return 0;
    183 }
  • 相关阅读:
    websocket 学习笔记
    oxy 学习笔记
    postcss
    一致性hash和chord
    leveldb 学习笔记
    logrus 学习笔记
    viper 学习笔记
    redigo 学习笔记
    gin 学习笔记
    修改TOMCAT的JVM虚拟机内存大小几种方式
  • 原文地址:https://www.cnblogs.com/zhsl/p/2992653.html
Copyright © 2020-2023  润新知