E - Swap Places
https://atcoder.jp/contests/abc289/tasks/abc289_e
思路
T 从 1 要到 4
A 从 4 要到 1
两人同步移动
每次移动到的目标节点,花色要求不同。
设置系统i时刻所处的位置为 <Ti, Ai>
系统agent是在一个二维空间移动
初始位置 <1, n>, 目标位置为 <n, 1>
问是否路径使得初始位置可以到达目标位置; 这样就转换为图的遍历问题。
使用dfs或者bfs算法。
需要注意的是, 二维位置 是否被访问过, 也需要使用二维数据结构来存储。
Code -- BFS
https://atcoder.jp/contests/abc289/submissions/38948249
BFS, 使用queue遍历
遍历过程中, 为提升效率, 不能使用 dfs 的是否访问过的 visited 标记法
需要使用 inque 是否添加到队列中 标记法,
即 已经入 队列, 后续在此遇到此节点也不需要使 此节点入队列。
int t; int n, m; vector<int> c; map<int, set<int> > edges; typedef struct { int tpos; int apos; int steps; } NODE; int bfs(){ map<int, map<int, bool> > inque; queue<NODE> qq; NODE node; node.tpos = 1; node.apos = n; node.steps = 0; qq.push(node); inque[1][0] = true; while(!qq.empty()){ NODE front = qq.front(); qq.pop(); int tpos = front.tpos; int apos = front.apos; int steps = front.steps; // cout << "------ tpos = " << tpos << endl; // cout << "------ apos = " << apos << endl; // cout << "------ steps = " << steps << endl; if (tpos == n && apos == 1){ // cout << steps << endl; return steps; } // do combination and add to queue for(auto tit: edges[tpos]){ for(auto ait: edges[apos]){ // skip if next pos colors are same if(c[tit] == c[ait]){ continue; } if (inque[tit][ait]){ continue; } // cout << "add one pair to queue" << endl; // cout << "tit = " << tit << endl; // cout << "ait = " << ait << endl; NODE node; node.tpos = tit; node.apos = ait; node.steps = steps + 1; qq.push(node); inque[tit][ait] = true; } } } return -1; } int main() { cin >> t; REP(i, t){ cin >> n >> m; c.clear(); c.push_back(0); REP(j, n){ int cj; cin >> cj; c.push_back(cj); } edges.clear(); REP(j, m){ int uj, vj; cin >> uj >> vj; edges[uj].insert(vj); edges[vj].insert(uj); } cout << bfs() << endl; } return 0; }
BFS visited标记法会TLE
如下代码BFS 确使用了 visited标记法, 导致运行时间超时
具体原因如下展示, 如果使用visited标记法, 导致3被入队列两次。
https://atcoder.jp/contests/abc289/submissions/38947638
int t; int n, m; vector<int> c; map<int, set<int> > edges; typedef struct { int tpos; int apos; int steps; } NODE; int bfs(){ map<int, map<int, bool> > vis; queue<NODE> qq; NODE node; node.tpos = 1; node.apos = n; node.steps = 0; qq.push(node); while(!qq.empty()){ NODE front = qq.front(); qq.pop(); int tpos = front.tpos; int apos = front.apos; int steps = front.steps; // cout << "------ tpos = " << tpos << endl; // cout << "------ apos = " << apos << endl; // cout << "------ steps = " << steps << endl; vis[tpos][apos] = true; if (tpos == n && apos == 1){ // cout << steps << endl; return steps; } // do combination and add to queue for(auto tit: edges[tpos]){ for(auto ait: edges[apos]){ // skip if next pos colors are same if(c[tit] == c[ait]){ continue; } if (vis[tit][ait]){ continue; } // cout << "add one pair to queue" << endl; // cout << "tit = " << tit << endl; // cout << "ait = " << ait << endl; NODE node; node.tpos = tit; node.apos = ait; node.steps = steps + 1; qq.push(node); } } } return -1; } int main() { cin >> t; REP(i, t){ cin >> n >> m; c.clear(); c.push_back(0); REP(j, n){ int cj; cin >> cj; c.push_back(cj); } edges.clear(); REP(j, m){ int uj, vj; cin >> uj >> vj; edges[uj].insert(vj); edges[vj].insert(uj); } cout << bfs() << endl; } return 0; }
标签:qq,node,Places,int,steps,Swap,uj,front From: https://www.cnblogs.com/lightsong/p/17131741.html