电路维修
Solution.1
双端队列搜索,权值为(0)的边放在队头,权值为(1)放在队尾
Code.1
#include<deque>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
deque<pair<int,int> > dq;
pair<int,int> t;
int T,n,m,dis[505][505], vis[505][505];
char a[505][505];
void work(int x,int y,int d,int bj){
if(dis[x][y] > d + bj){
dis[x][y] = d + bj;
if(bj) dq.push_back(pair <int, int> (x, y));
else dq.push_front(pair <int, int> (x, y));
}
}
void BFS()
{
int x, y, now;
dq.clear();
dq.push_front(pair <int, int> (1, 1));
memset(dis, 0x7f, sizeof dis);
memset(vis, 0, sizeof(vis));
dis[1][1] = 0;//多次数据记得初始化
while(!dq.empty()){
t = dq.front();
dq.pop_front();
x = t.first, y = t.second;
now = dis[x][y];
if(vis[x][y]){
continue;
}
vis[x][y] = 1;
if(x > 1 && y > 1) work(x - 1, y - 1, now, a[x-1][y-1] != '\');
if(x > 1 && y <= m) work(x - 1, y + 1, now, a[x-1][y] != '/');
if(x <= n && y > 1) work(x + 1, y - 1, now, a[x][y-1] != '/');
if(x <= n && y <= m) work(x + 1, y + 1, now, a[x][y] != '\');
}
printf("%d
",dis[n+1][m+1]);
}
int main(){
scanf("%d", &T);
for(int i = 1; i <= T; ++i){
scanf("%d%d", &n, &m);
for(int j = 1; j <= n; ++j) scanf("%s", a[j] + 1);
if((n + m) % 2){
printf("NO SOLUTION
");
continue;
}
BFS();
}
return 0;
}
Solution.2
最短路,复习(dji),因为可能双向边,以及其他的某种情况,所以要记录(vis[i]),(pair)是先比较(frst),然后比较(second)
Code.2
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>
#include <queue>
#include <cmath>
using std::priority_queue;
using std::pair;
using std::make_pair;
using std::greater;
using std::vector;
typedef pair<int,int> Pair;
const int N = 505000;
const int M = 2e6;
struct Edge{
int to, val, next;
}e[M];
int cnt, head[N], dis[N], vis[N];
char s[505];
inline void addedge(int x, int y, int z){
e[++cnt].to = y;
e[cnt].next = head[x];
e[cnt].val = z;
head[x] = cnt;
return;
}
inline void dji(){
memset(vis, 0, sizeof(vis));
memset(dis, 0x3f, sizeof(dis));
priority_queue <Pair, vector<Pair>, greater<Pair> > q;
dis[1] = 0;
q.push(make_pair(0, 1));
while(!q.empty()){
Pair u = q.top();
q.pop();
if(vis[u.second]) continue;
vis[u.second] = 1;
for(int i = head[u.second]; i; i = e[i].next){
if(dis[u.second] + e[i].val < dis[e[i].to]){
dis[e[i].to] = dis[u.second] + e[i].val;//即便是已经被水流流过的点,也可能更新
if(!vis[e[i].to]){
q.push(make_pair(dis[e[i].to], e[i].to));
}
}
}
}
}
int main(){
int t;
scanf("%d", &t);
while(t--){
memset(head, 0, sizeof(head));
memset(e, 0, sizeof(e));
cnt = 0;
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1, la, lb, lc, ld; i <= n; ++i){
scanf("%s", s + 1);
for(int j = 1; j <= m; ++j){
if(s[j] == '/'){
la = (m + 1) * (i - 1) + j;
lb = (m + 1) * (i - 1) + j + 1;
lc = (m + 1) * i + j;
ld = (m + 1) * i + j + 1;
addedge(lb, lc, 0);
addedge(lc, lb, 0);
addedge(la, ld, 1);
addedge(ld, la, 1);
}else{
la = (m + 1) * (i - 1) + j;
lb = (m + 1) * (i - 1) + j + 1;
lc = (m + 1) * i + j;
ld = (m + 1) * i + j + 1;
addedge(lb, lc, 1);
addedge(lc, lb, 1);
addedge(la, ld, 0);
addedge(ld, la, 0);
}
}
}
dji();
if(dis[(m + 1) * (n + 1)] == 1061109567)
puts("NO SOLUTION");
else printf("%d
", dis[(m + 1) * (n + 1)]);
}
return 0;
}