day2.电路维修
双端队列:特殊的dijkstra
总结:回顾dijkstra的过程,就是每次找到一个距离最小的点,用其更新其他点,可以用优先队列来维护距离最小的点,发现用deque将边权为0的点插入队头,为1的点插入队
尾,效果一样,但每次操作时间复杂度由\(log(n) -> O(1)\)
注意点的坐标和线的坐标差一格,最后应该到(n,m)
#include<cstring>
#include<iostream>
#include<algorithm>
#include<deque>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
const int N = 510,M = N*N;
int n,m;
char g[N][N];
int dist[N][N];
bool st[N][N];
int bfs()
{
memset(dist,0x3f,sizeof dist);
memset(st,0,sizeof st);
dist[0][0] = 0;
deque<PII> q;
q.push_back({0,0});
string s= "\\/\\/";
int dx[4] = {-1,-1,1,1},dy[4] = {-1,1,1,-1};//坐标周围四个点
int ix[4] = {-1,-1,0,0},iy[4] = {-1,0,0,-1};// 周围四个条线
while(q.size())
{
auto t = q.front();
q.pop_front();
if(st[t.x][t.y]) continue;
st[t.x][t.y] = true;
for(int i = 0;i < 4;i++)
{
int a = t.x + dx[i],b = t.y + dy[i];
if(a < 0 || a > n || b < 0 ||b > m) continue;
int ca = t.x + ix[i],cb = t.y + iy[i];
int d = dist[t.x][t.y] + (g[ca][cb] != s[i]);
if(d < dist[a][b])
{
dist[a][b] = d;
if(g[ca][cb] != s[i]) q.push_back({a,b});
else q.push_front({a,b});
}
}
}
return dist[n][m];
}
int main()
{
int t;cin>>t;
while(t--)
{
cin>>n>>m;
for(int i = 0;i < n;i++) scanf("%s",g[i]);
int t = bfs();
if(t == 0x3f3f3f3f) puts("NO SOLUTION");
else printf("%d\n",t);
}
return 0;
}
Tips:\表示是\\

浙公网安备 33010602011771号