【BZOJ】【2595】【WC2008】游览计划
Orz zky神犇http://blog.csdn.net/iamzky/article/details/42029921
spfa的灵活应用!(好像是求了一个叫做斯坦纳树的东西……)
o(︶︿︶)o 唉我就是太水了,离散化写跪了,x*1e5+y*1e4+k,但是这题里我x和y的范围是[1,10]所以在y==10的时候会出错!!
1 //BZOJ 2595 2 #include<queue> 3 #include<cmath> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 #define rep(i,n) for(int i=0;i<n;++i) 10 #define F(i,j,n) for(int i=j;i<=n;++i) 11 #define D(i,j,n) for(int i=j;i>=n;--i) 12 using namespace std; 13 const int N=13,INF=~0u>>2; 14 const int fx[]={1,0,-1,0}, 15 fy[]={0,1,0,-1}; 16 typedef long long LL; 17 //#define debug 18 int n,m,a[N][N],d[N][N],cnt=0; 19 int f[N][N][1100],pre[N][N][1100]; 20 bool vis[N][N]; 21 22 struct node{ int x,y; }; 23 queue<node>Q; 24 inline int pack(int x,int y,int s){ 25 return x*1000000+y*10000+s; 26 } 27 28 void spfa(int Set){ 29 while(!Q.empty()){ 30 int x=Q.front().x,y=Q.front().y; Q.pop(); 31 vis[x][y]=0; 32 rep(i,4){ 33 int tx=x+fx[i],ty=y+fy[i]; 34 if (tx<1 || ty<1 || tx>n || ty>m) continue; 35 36 if (f[tx][ty][Set]>f[x][y][Set]+a[tx][ty]){ 37 f[tx][ty][Set]=f[x][y][Set]+a[tx][ty]; 38 pre[tx][ty][Set]=pack(x,y,Set); 39 if (!vis[tx][ty]) Q.push((node){tx,ty}),vis[tx][ty]=1; 40 } 41 } 42 } 43 } 44 45 void dfs(int i,int j,int Set){ 46 if (pre[i][j][Set]==INF || pre[i][j][Set]%5000==0)return; 47 vis[i][j]=1; 48 int x=pre[i][j][Set]/1000000, 49 y=(pre[i][j][Set]-x*1000000)/10000, 50 z=(pre[i][j][Set]-x*1000000-y*10000); 51 #ifdef debug 52 printf("%d,%d,%d----->%d,%d,%d\n",x,y,z,i,j,Set); 53 #endif 54 dfs(x,y,z); 55 if (x==i && y==j) dfs(i,j,Set-z); 56 } 57 58 void solve(){ 59 for(int Set=1;Set<(1<<cnt);Set++){ 60 F(x,1,n) F(y,1,m){ 61 for(int s=Set&(Set-1);s;s=(s-1)&Set){ 62 if(f[x][y][Set]>f[x][y][s]+f[x][y][Set-s]-a[x][y]){ 63 f[x][y][Set]=f[x][y][s]+f[x][y][Set-s]-a[x][y]; 64 pre[x][y][Set]=pack(x,y,s); 65 } 66 } 67 if (f[x][y][Set]!=INF){Q.push((node){x,y}); vis[x][y]=1;} 68 } 69 spfa(Set); 70 } 71 int x,y; 72 F(i,1,n) F(j,1,m) if (!a[i][j]) {x=i; y=j;break;} 73 printf("%d\n",f[x][y][(1<<cnt)-1]); 74 75 #ifdef debug 76 F(i,1,n) F(j,1,m) 77 F(k,0,(1<<cnt)-1) 78 if (pre[i][j][k]!=INF) 79 printf("pre[%d][%d][%d]=%d\n",i,j,k,pre[i][j][k]); 80 #endif 81 dfs(x,y,(1<<cnt)-1); 82 F(i,1,n) F(j,1,m){ 83 if (!a[i][j]) putchar('x'); 84 else if(vis[i][j]) putchar('o'); 85 else putchar('_'); 86 if (j==m) puts(""); 87 } 88 } 89 90 int main(){ 91 #ifndef ONLINE_JUDGE 92 freopen("file.in","r",stdin); 93 // freopen("file.out","w",stdout); 94 #endif 95 scanf("%d%d",&n,&m); 96 F(i,0,10) F(j,0,10) 97 F(k,0,(1<<10)) f[i][j][k]=pre[i][j][k]=INF; 98 F(i,1,n) 99 F(j,1,m){ 100 scanf("%d",&a[i][j]); 101 if (!a[i][j]) 102 f[i][j][1<<(cnt++)]=0; 103 } 104 solve(); 105 return 0; 106 }