POJ-1739 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 }

 

你可能感兴趣的:(poj)