1. 程式人生 > >洛谷 P4294 [WC2008]遊覽計劃

洛谷 P4294 [WC2008]遊覽計劃

自己 putc size color char 最小 line clas 生成樹

題目鏈接

不是很會呢,但似乎抄了題解後有點明白了

sol:狀態DP顯然,其實是要構建一棵最小生成樹一樣的東西,我自己的理解(可能不是很對哦希望多多指教)f[x][y][zt]就是到x,y這個點,狀態為zt,時的最小代價於是有兩種轉移方法:一種是若zt1|zt2=zt且zt1&zt2==0,那麽f[x][y][zt]=min(f[x][y][zt],f[x][y][zt1]+f[x][y][zt2]),第二種就是跑spfa,如x1,y1和x,y聯通,f[x1][y1][zt‘‘‘]=min(f[x1][y1][zt‘‘‘],f[x][y][zt]+v[x1][y1]) 看起來不是很難,實現起來對菜雞來說可費勁了qaq

#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=12,B=(1<<11),inf=1e7,dx[]={-1,1,0,0},dy[]={0,0,-1,1};
int n,m,f[N][N][B],v[N][N],tot=0,SX,SY,inq[N][N],re[N][N];
queue<pair<int,int> >q;
struct node
{
    int x,y,zt;
}pre[N][N][B];
inline 
void spfa(int zt) { int i,xx,yy; pair<int,int>pp; while(!q.empty()) { pp=q.front(); q.pop(); inq[pp.first][pp.second]=0; for(i=0;i<4;i++) { xx=pp.first+dx[i]; yy=pp.second+dy[i]; if(xx<1||xx>n||yy<1||yy>m)continue; if(f[xx][yy][zt]>f[pp.first][pp.second][zt]+v[xx][yy]) { f[xx][yy][zt]
=f[pp.first][pp.second][zt]+v[xx][yy]; pre[xx][yy][zt]=(node){pp.first,pp.second,zt}; if(!inq[xx][yy]) q.push(make_pair(xx,yy)),inq[xx][yy]=1; } } } } inline void dfs(int x,int y,int zt) { if(!pre[x][y][zt].zt)return; re[x][y]=1; node tmp=pre[x][y][zt]; dfs(tmp.x,tmp.y,tmp.zt); if(tmp.x==x&&tmp.y==y)dfs(x,y,zt^tmp.zt); } int main() { int i,j,zt,zz; scanf("%d%d",&n,&m); memset(f,63,sizeof f); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&v[i][j]); if(!v[i][j]) f[i][j][1<<tot]=0,SX=i,SY=j,tot++; } } for(zt=0;zt<(1<<tot);zt++) { while(!q.empty()) q.pop(); memset(inq,0,sizeof inq); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { for(zz=zt;zz;zz=zt&(zz-1)) { if(f[i][j][zt]>f[i][j][zz]+f[i][j][zt^zz]-v[i][j]) { f[i][j][zt]=f[i][j][zz]+f[i][j][zt^zz]-v[i][j]; pre[i][j][zt]=(node){i,j,zz}; } }if(f[i][j][zt]<inf) q.push(make_pair(i,j)),inq[i][j]=1; } }spfa(zt); }printf("%d\n",f[SX][SY][(1<<tot)-1]); dfs(SX,SY,(1<<tot)-1); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(!v[i][j])putchar(x);else if(re[i][j])putchar(o);else putchar(_); }puts(""); }return 0; }

洛谷 P4294 [WC2008]遊覽計劃