「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On [最短路 01BFS]
P2243 电路维修 #2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On
建图比较难想 若为'\'型 将其左上角与右下角连一条为0的边 右上角与左下角连一条为1的边 另一种情况相反
然后跑一个01BFS
就是lch讲的BFS可以跑最短路的情况 边权只能为0或1
#include<bits/stdc++.h> using namespace std; #define rg register const int N=500+5,M=1e6+5,inf=0x3f3f3f3f,P=9999973; int T,n,m,k; char a[N][N]; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } int head[M],tot=0; struct edge{int v,w,nxt;}e[M<<1]; void add(int u,int v,int w){ e[++tot]=(edge){v,w,head[u]},head[u]=tot; } int id(int x,int y){ return x*(m+1)+y; } bool vis[M]; int dis[M]; void bfs(int x){ memset(vis,0,sizeof(vis)); memset(dis,inf,sizeof(dis)); deque<int>q; q.push_back(x),dis[x]=0; while(!q.empty()){ int u=q.front(); q.pop_front(); if(vis[u]) continue; vis[u]=1; for(int i=head[u],v,w;i;i=e[i].nxt){ v=e[i].v,w=e[i].w; if(vis[v]) continue; if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; if(!w) q.push_front(v); else q.push_back(v); } } } } int main(){ freopen("in.txt","r",stdin); rd(T); for(int cas=1;cas<=T;++cas){ tot=0; memset(head,0,sizeof(head)); rd(n),rd(m); for(int i=1;i<=n;++i) scanf("%s",a[i]+1); if((m+n)%2) puts("NO SOLUTION"); else{ for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ if(a[i][j]=='\\') add(id(i-1,j-1),id(i,j),0), add(id(i,j),id(i-1,j-1),0), add(id(i,j-1),id(i-1,j),1), add(id(i-1,j),id(i,j-1),1); else add(id(i,j-1),id(i-1,j),0), add(id(i-1,j),id(i,j-1),0), add(id(i,j),id(i-1,j-1),1), add(id(i-1,j-1),id(i,j),1); } bfs(0); printf("%d\n",dis[id(n,m)]); } } return 0; }