Ural 1519 Formula 1 插头DP(单回路)
2013-04-01 01:10
363 查看
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1519
一条哈密顿回路路,反正是写到蛋疼了,不过终于解决了,插头DP这玩意,太容易出错了,要注意block的处理。
一条哈密顿回路路,反正是写到蛋疼了,不过终于解决了,插头DP这玩意,太容易出错了,要注意block的处理。
//STATUS:C++_AC_343MS_961KB #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<iostream> #include<string> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> using namespace std; #define LL long long #define pii pair<int,int> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const int N=15,INF=0x3f3f3f3f,MOD=4001,STA=1000010; const double DNF=100000000000; int g ,code ,ma ; int n,m,ex,ey; struct Hash{ int first[MOD],next[STA],size; LL f[STA],sta[STA]; void init(){ size=0; mem(first,-1); } void add(LL st,LL ans){ int i,u=st%MOD; for(i=first[u];i!=-1;i=next[i]){ if(sta[i]==st){ f[i]+=ans; return; } } sta[size]=st; f[size]=ans; next[size]=first[u]; first[u]=size++; } }hs[2]; void shift(int p) //换行移位 { int k; LL sta; for(k=0;k<hs[!p].size;k++){ sta=hs[!p].sta[k]<<3; hs[p].add(sta,hs[!p].f[k]); } } LL getsta() //最小表示法 { LL i,cnt=1,sta=0; mem(ma,-1); ma[0]=0; for(i=0;i<=m;i++){ if(ma[code[i]]==-1)ma[code[i]]=cnt++; code[i]=ma[code[i]]; sta|=(LL)code[i]<<(3*i); } return sta; } void getcode(LL sta) { int i; for(i=0;i<=m;i++){ code[i]=sta&7; sta>>=3; } } void unblock(int i,int j,int p) { int k,t; LL cnt,x,y; for(k=0;k<hs[!p].size;k++){ getcode(hs[!p].sta[k]); x=code[j],y=code[j+1]; cnt=hs[!p].f[k]; if(x && y){ //合并连通分量 code[j]=code[j+1]=0; if(x!=y){ for(t=0;t<=m;t++) if(code[t]==y)code[t]=x; hs[p].add(getsta(),cnt); } else if(i==ex && j==ey){ //最后一个点特殊处理 hs[p].add(getsta(),cnt); } } else if(x&&!y || !x&&y){ //延续连通分量 t=x?x:y; if(g[i+1][j]){ code[j]=t;code[j+1]=0; hs[p].add(getsta(),cnt); } if(g[i][j+1]){ code[j]=0;code[j+1]=t; hs[p].add(getsta(),cnt); } } else if(g[i+1][j] && g[i][j+1]){ //创建新连通分量 code[j]=code[j+1]=8; hs[p].add(getsta(),cnt); } } } void block(LL j,int p) { int k; for(k=0;k<hs[!p].size;k++){ getcode(hs[!p].sta[k]); code[j]=code[j+1]=0; hs[p].add(getsta(),hs[!p].f[k]); } } LL slove() { int i,j,p; hs[0].init(); hs[p=1].init(); hs[0].add(0,1); for(i=0;i<n;i++){ for(j=0;j<m;j++){ if(g[i][j])unblock(i,j,p); else block(j,p); //p=!p优化 hs[p=!p].init(); } shift(p); //换行移位 hs[p=!p].init(); } for(i=0;i<hs[!p].size;i++){ if(hs[!p].sta[i]==0)return hs[!p].f[i]; } return 0; } int main() { // freopen("in.txt","r",stdin); int i,j; LL ans; char c; while(~scanf("%d%d",&n,&m) && (n || m)) { mem(g,0); ex=-1; for(i=0;i<n;i++){ for(j=0;j<m;j++){ scanf(" %c",&c); g[i][j]=(c=='.'); if(g[i][j])ex=i,ey=j; } } if(ex==-1)ans=0; else ans=slove(); printf("%I64d\n",ans); } return 0; }
相关文章推荐
- Ural1519 Formula 1 插头dp入门
- URAL1519 Formula 1 【插头dp】
- [ural1519]Formula 1 && 插头DP
- URAL 1519 Formula 1(插头DP,入门题)
- URAL1519 Formula 1(插头dp的基础题 ——详细解释)
- ural 1519 Formula 1 插头dp 一条回路
- bzoj 1814: Ural 1519 Formula 1 插头dp经典题
- HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)
- [ural1519]Formula 1 && 插头DP(括号表示法)
- URAL 1519 Formula 1 插头DP
- 【bzoj1814】Ural 1519 Formula 1 插头dp
- 【URAL 1519】【插头dp模板】Formula 1
- URAL 1519 Formula 1 (插头DP,常规)
- 【BZOJ1814】Ural 1519 Formula 1 插头DP
- URAL 1519 Formula 1 dp(插头)
- 【Ural1519】Formula 1 插头DP模板
- [省选前题目整理][URAL 1519]Formula 1(插头DP)
- [URAL1519] Formula 1 [插头dp入门]
- URAL 1519 Formula 1(插头DP)
- URAL 1519 Formula 1 【插头DP模板题】