URAL 1016. Cube on the Walk (分层图+最短路)

URAL 1016. Cube on the Walk (分层图+最短路)_第1张图片URAL 1016. Cube on the Walk (分层图+最短路)_第2张图片

 一个正方体,每个面标了一个数字,问,这个正方体,在8*8的棋盘上,从起点滚动到终点,所有朝下的面的数字之和的最小值(包括起点和终点)。

正方体,经过旋转,最多有24种状态。建立分层图,点数:24*8*8=1536.  稀疏图,用 SPFA 算法求最短路。

我直接写的一维数组。节点编号= 正方体的状态*64 +横坐标*8 +纵坐标 ;

开始求出所有24个状态(特殊情况可能少于24种状态)之间的状态转移。

然后SPFA求最短路。

using namespace std;
int dx[4]={-1, 1, 0, 0};
int dy[4]={ 0, 0, 1,-1};
int de[4]={ 5, 3, 1, 0};
struct Dice{
	int a[6];//按照题目给的顺序,分别为前,后,上,右,下,左 
	int next[4];//四个方向旋转后的编号
	void turn(int i){
		switch(i){
			case 0:left();break;
			case 1:right();break;
			case 2:up();break;
			case 3:down();break;
		}
	}
	void left(){int t=a[5];a[5]=a[2];a[2]=a[3];a[3]=a[4];a[4]=t;}//向左滚动
	void right(){int t=a[5];a[5]=a[4];a[4]=a[3];a[3]=a[2];a[2]=t;}//向右滚动
	void up(){int t=a[0];a[0]=a[4];a[4]=a[1];a[1]=a[2];a[2]=t;}//向上滚动
	void down(){int t=a[0];a[0]=a[2];a[2]=a[1];a[1]=a[4];a[4]=t;}//向下滚动
	bool operator ==(const Dice&B)const{
		int T=0;
		for(int i=0;i<6;i++) T+=a[i]==B.a[i];
		return T==6;
	}
	void show(){
		printf("\t(%d,%d,%d,%d,%d,%d)\n",a[0],a[1],a[2],a[3],a[4],a[5]);
	}
}D[24];int Dn;//记录24种状态
struct Node{
	int path;//记录最短路径
	int Dis;//记录最小值
	void init(int k){
		Dis=-1;path=k;
	}
}game[1536];
queue Q;
bool inq[1536];
void Bfs(int k){
	int tempk=k;
	int index=tempk/64;tempk%=64;
	int x=tempk/8,y=tempk%8;
	for(int i=0;i<4;i++){//向4个方向扩展 
		int nx=x+dx[i],ny=y+dy[i];
		int Next=D[index].next[i]*64+nx*8+ny;//计算下个节点的编号 
		if(nx>=0&&nx<8&&ny>=0&&ny<8){//如果下一点在棋盘内 
			int Distance=game[k].Dis+D[index].a[de[i]];
			if(!~game[Next].Dis||Distance>a;Sx=a[0]-'a';Sy=a[1]-'1';
	cin>>a;Dx=a[0]-'a';Dy=a[1]-'1';
	for(int i=0;i<6;i++) scanf("%d",&D[0].a[i]);
	//求出24状态之间的状态转移。
	Dn=1;
	for(int i=0;i%d",D[i].next[k]);
		cout<




你可能感兴趣的:(图论,URAL)