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