#include<iostream> #include<cstring> usingnamespacestd; #define IOS \ ios::sync_with_stdio(false); \ cin.tie(0); \ cout.tie(0) constint N = 1e5+ 5; int h[N], e[N], ne[N], idx; int d[N],q[N]; int n,m;
voidadd(int a, int b)// 添加一条边a->b { e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ; }
intbfs(){ q[0] = 1; int head = 0,tail = 0; memset(d,-1,sizeof d); d[1] = 0; while (head <= tail){ int t = q[head++]; for (int i = h[t]; ~i;i = ne[i]){ int j = e[i]; if (d[j] == -1){ d[j] = d[t] + 1; q[++tail] = j; } } } return d[n];// 能到达n号点则返回距离,否则返回-1 }
intmain(){ IOS; memset(h, -1, sizeof h); cin >> n >> m; int a,b; for (int i = 0; i < m; i ++ ){ cin >> a >> b; add(a, b); } cout << bfs() << '\n'; return0; }
在一个 3×3 的网格中,1∼8 这 8 个数字和一个 x 恰好不重不漏地分布在这 3×3 的网格中。 例如: 123 x 46 758 在游戏过程中,可以把 x 与其上、下、左、右四个方向之一的数字交换(如果存在)。 我们的目的是通过交换,使得网格变为如下排列(称为正确排列): 123 456 78 x 例如,示例中图形就可以通过让 x 先后与右、下、右三个方向的数字交换成功得到正确排列。 交换过程如下: 123123123123 x 464 x 6456456 7587587 x 878 x 现在,给你一个初始网格,请你求出得到正确排列至少需要进行多少次交换。
输入格式 输入占一行,将 3×3 的初始网格描绘出来。 例如,如果初始网格如下所示: 123 x 46 758 则输入为:123 x 46758
int dx[] = {-1,1,0,0},dy[] = {0,0,-1,1};// 坐标偏移量 while (q.size()){ string t = q.front(); q.pop();// 取队头并出队
int dist = d[t];// 存储当前状态距离 if (t == end) return dist;// 走到终止状态,退出 int k = t.find('x'); int x = k / 3,y = k % 3;// 一维数组下标-->二维数组下标小技巧 for (int i = 0;i < 4;i ++){ int a = x + dx[i],b = y + dy[i]; if (a >= 0 && a < 3 && b >= 0 && b < 3){ // 这个string内部字符的swap操作太妙了!!! swap(t[k],t[3*a+b]);// 状态转移,二维数组下标-->一维数组下标 if (!d.count(t)){// t状态未遍历过 d[t] = dist + 1;// 更新距离 q.push(t);// 入队 } swap(t[k],t[3*a+b]);// 还原状态,为下一种转换情况做准备 } } }// 无法转换到目标状态,返回-1 return-1; }
int dx[] = {-1,1,0,0},dy[] = {0,0,-1,1};// 坐标偏移量 while (q.size()){ string t = q.front(); q.pop();// 取队头并出队
int dist = d[gethash(t)];// 存储当前状态距离 if (t == end) return dist;// 走到终止状态,退出 int k = t.find('x'); int x = k / 3,y = k % 3;// 一维数组下标-->二维数组下标小技巧 for (int i = 0;i < 4;i ++){ int a = x + dx[i],b = y + dy[i]; if (a >= 0 && a < 3 && b >= 0 && b < 3){ swap(t[k],t[3*a+b]);// 状态转移,二维数组下标-->一维数组下标 if (!d[gethash(t)]){// t状态未遍历过 d[gethash(t)] = dist + 1;// 更新距离 q.push(t);// 入队 } swap(t[k],t[3*a+b]);// 还原状态,为下一种转换情况做准备 } } }// 无法转换到目标状态,返回-1 return-1; }