BZOJ 1006
HEOI2015乱做

BZOJ 2595 游览计划

HJWJBSR posted @ 2015年9月21日 16:36 in 题解 , 572 阅读

斯坦纳树早在6月份吧小狗就讲过了然而当时并没有填这个坑

感觉写起来还是很轻松愉快的不过虽然这么说还是被细节卡了好久

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 13
#define M 1024
#define INF 0x3f7f7f7f
int v[N][N],st,S,la[N][N][M][4],li[M*M][3];
int s[N][N][M],a[N][2],n,m;bool b[N][N][M];
const int dir[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
inline int Read()
 {
 	int x=0;char y;
 	do y=getchar(); while (y<'0'||y>'9');
 	do x=x*10+y-'0',y=getchar(); while (y>='0'&&y<='9');
 	return x;
 }
inline void Trans(int x,int y,int z,int o,int p,int *ri)
 {
 	if (!o||!p||o>n||p>m||v[o][p]+s[x][y][z]>=s[o][p][z])
 	  return;
 	s[o][p][z]=v[o][p]+s[x][y][z];
 	la[o][p][z][0]=x;la[o][p][z][1]=y;la[o][p][z][2]=z;
 	la[o][p][z][3]=0;
 	if (!b[o][p][z])
 	  (*ri)++,b[li[*ri][0]=o][li[*ri][1]=p][li[*ri][2]=z]=1;
 }
void SPFA(int t)
 {
 	int le=1,ri=0;
 	for (int i=1;i<=n;i++)
 	 for (int j=1;j<=m;j++)
 	  if (s[i][j][t]!=INF)
 	  	li[++ri][0]=i,li[ri][1]=j,li[ri][2]=t,
 	    b[i][j][t]=1;
 	for (;le<=ri;le++)
 	 {
 	 	int q=li[le][0],w=li[le][1],e=li[le][2];
 	 	for (int i=0;i<4;i++)
 	 	  Trans(q,w,e,dir[i][0]+q,dir[i][1]+w,&ri);
 	 	b[q][w][e]=0;
 	 }
 	return;
 }
void Solve()
 {
 	for (int i=1;i<=n;i++)
 	 for (int j=1;j<=m;j++)
 	  for (int k=1;k<S;k++)
 	  	s[i][j][k]=INF;
 	for (int i=1;i<=n;i++)
 	 for (int j=1;j<=m;j++)
 	   s[i][j][0]=v[i][j];
 	for (int i=1;i<=st;i++)
 	  s[a[i][0]][a[i][1]][1 << i - 1]=0;
 	for (int t=0;t<S;t++)
 	 {
 	 	for (int i=(t-1)&t;i;i=(i-1)&t)
 	 	 for (int j=1;j<=n;j++)
 	 	  for (int k=1;k<=m;k++)
 	 	   if (s[j][k][t]>s[j][k][i]+s[j][k][t-i]-v[j][k])
 	 	    {
 	 	       s[j][k][t]=s[j][k][i]+s[j][k][t-i]-v[j][k];
 	 	       la[j][k][t][0]=j;la[j][k][t][1]=k;
 	 	       la[j][k][t][2]=i;la[j][k][t][3]=t-i;
 	 	    }
 	 	SPFA(t);
 	 }
 }
void DFS(int x,int y,int z)
 {
 	if (v[x][y]) v[x][y]=-1;
 	if (!la[x][y][z][0]) return;
 	if (la[x][y][z][3])
 	  DFS(x,y,la[x][y][z][2]),DFS(x,y,la[x][y][z][3]);else
 	  DFS(la[x][y][z][0],la[x][y][z][1],la[x][y][z][2]);
 }
void Print()
 {
 	DFS(a[1][0],a[1][1],S-1);
 	printf("%d\n",s[a[1][0]][a[1][1]][S-1]);
 	for (int i=1;i<=n;i++)
 	 {
 	 	for (int j=1;j<=m;j++)
 	   	 if (!v[i][j]) putchar('x');else
 	   	 if (v[i][j]==-1) putchar('o');else
 	   	   putchar('_');
 	   	puts("");
 	 }
 }
int main()
 {
 	n=Read();m=Read();
 	for (int i=1;i<=n;i++)
 	 for (int j=1;j<=m;j++)
 	  {
 	  	 v[i][j]=Read();
 	  	 if (!v[i][j])
 	  	   a[++st][0]=i,a[st][1]=j;
 	  }
 	S=1 << st;
 	Solve();
 	Print();
 	return 0;
 }

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter