[Time Gate]
https://www.luogu.org/problemnew/show/P2243
【解题思路】
对于每个方格,需要标记四个点
确定了四个点的位置,接下来就只需要连边了。(好在这道题对于内存没限制,随便开简直爽。) 如果'/'就右上到左下连边,这条边权值为0(val=0)。连边要连双向
同时也要双向的连一条从左上到右下的边,权值为1,表示旋转后的边
如果是’\‘则反之。
用左上角的点来表示'/’还是'\'
ans=1到(R+1)*(C+1)的最短路啦。
【code】
1 ```cpp 2 #include <cstdio> 3 #include <queue> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 const int inf=1<<30; 9 int T,r,c,cnt; 10 char a[505][505]; 11 struct Node{ 12 int End; 13 int nxt; 14 int w; 15 }edge[505*505*4]; 16 int head[505*505*4]; 17 bool flag[505*505*4]; 18 int dis[505*505*4]; 19 priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q; 20 void Add(int u,int v,int ww){ 21 edge[++cnt].nxt=head[u]; 22 head[u]=cnt; 23 edge[cnt].End=v; 24 edge[cnt].w=ww; 25 } 26 int main(){ 27 //freopen("2243.in","r",stdin); 28 //freopen("2243.out","w",stdout); 29 scanf("%d",&T); 30 scanf("%d%d",&r,&c); 31 while(T--){ 32 cnt=0; 33 memset(edge,0,sizeof edge); 34 memset(head,0,sizeof head); 35 scanf("%d%d",&r,&c); 36 for(int i=1;i<=r;++i){ 37 char s[510]; 38 scanf("%s",&s); 39 for(int j=1;j<=c;++j){ 40 int p1=((i-1)*(c+1)+j); 41 int p2=(i*(c+1)+j+1); 42 int p3=((i-1)*(c+1)+j+1); 43 int p4=(i*(c+1)+j); 44 if(s[j-1]=='/'){ 45 Add(p1,p2,1); 46 Add(p2,p1,1); 47 Add(p3,p4,0); 48 Add(p4,p3,0); 49 } 50 else{ 51 Add(p1,p2,0); 52 Add(p2,p1,0); 53 Add(p3,p4,1); 54 Add(p4,p3,1); 55 } 56 } 57 } 58 for(register int i=1; i<=(r+1)*(c+1);i++) 59 dis[i]=inf; 60 memset(flag,0,sizeof(flag)); 61 dis[1]=0; 62 q.push(make_pair(0,1)); 63 while(!q.empty()){ 64 //pair<int,int> now=q.top(); 65 int x=q.top().second; 66 q.pop(); 67 if(flag[x])continue; 68 flag[x]=1; 69 for(int i=head[x];i;i=edge[i].nxt) 70 if(dis[x]+edge[i].w<dis[edge[i].End]){ 71 dis[edge[i].End]=dis[x]+edge[i].w; 72 if(!flag[edge[i].End]) 73 q.push(make_pair(dis[edge[i].End],edge[i].End)); 74 } 75 } 76 if(dis[(r+1)*(c+1)]==inf) 77 printf("NO SOLUTION\n"); 78 else printf("%d\n",dis[(r+1)*(c+1)]); 79 } 80 return 0; 81 } 82 ```