洛谷P2243 电路维修

时间:2024-01-17 10:22:38

题目地址

转化为图论问题

对于每个交叉点(X,Y)抽象成节点。与它相邻的四个点中,可以直接连线的边权为0,否则边权为1。

用死了的SPFA解决图论问题。

#include <cstring>
#include <cstdio>
#define GC getchar()
#define Clean(X,K) memset(X,K,sizeof(X))
#define re register
#define Hash(X,Y) ((X)*(M+1)+(Y))
using namespace std ;
int Qread () {
int X = ;
char C = GC ;
while (C > '' || C < '') C = GC ;
while (C >='' && C <='') {
X = X * + C - '' ;
C = GC ;
}
return X ;
}
const int Maxn = , INF = ;
int Times , N , M , Head[Maxn * Maxn] , En = , Q[Maxn * Maxn] , Mdis[Maxn * Maxn], Vis[Maxn * Maxn];
struct Edge {
int From , Goto , NextEdge , Len ;
};
Edge E[Maxn * Maxn * ] ;
void Adg (int X , int Y ,int L) {
E[++En].From = X ;
E[En].Goto = Y ;
E[En].Len = L ;
E[En].NextEdge = Head[X] ;
Head[X] = En ;
}
int SPFA () {
re int H = , T = ;
Clean(Vis , ) , Clean(Mdis , 0x3f) ;
const int St = Hash( , ) , Top = (N + ) * (M + );
if (++T > Top) T = ;
Q[T] = St , Mdis[St] = , Vis[St] = ;
while (H != T) {
if (++ H > Top) H = ;
const int Now = Q[H] ;
Vis[Now] = ;
for (re int i = Head[Now ] ; i ; i = E[i].NextEdge ) {
int Dis = Mdis[Now] + E[i].Len ;
if (Dis < Mdis[E[i].Goto ]) {
Mdis[E[i].Goto ] = Dis ;
if (!Vis[E[i].Goto ]) {
Vis[E[i].Goto ] = ;
if (++ T > Top) T = ;
Q[T] = E[i].Goto ;
}
}
}
}
return Mdis[Hash(N , M)] ;
}
int main () {
//freopen ("P2243.in" , "r" , stdin) ;
Times = Qread () ;
while (Times -- ) {
N = Qread () , M = Qread () ;
Clean (Head , ) , En = ;
for (re int i = ; i < N ; ++ i) {
for (re int j = ; j < M; ++ j) {
char C = GC ;
while (C !='\\' && C !='/') C = GC ;
if (C == '/') {
Adg (Hash(i + , j + ) , Hash (i , j) , ) ;
Adg (Hash (i , j) ,Hash(i + , j + ) , ) ;
Adg (Hash(i + , j) , Hash (i , j + ) , ) ;
Adg (Hash (i , j + ) ,Hash(i + , j) , ) ;
} else if (C == '\\') {
Adg (Hash(i + , j + ) , Hash (i , j) , ) ;
Adg (Hash (i , j) ,Hash(i + , j + ) , ) ;
Adg (Hash(i + , j) , Hash (i , j + ) , ) ;
Adg (Hash (i , j + ) ,Hash(i + , j) , ) ;
}
}
}
int Ans = SPFA() ;
if (Ans < INF)printf ("%d\n" , Ans) ;
else printf ("NO SOLUTION\n") ;
}
fclose (stdin) , fclose (stdout) ;
return ;
}