LOJ2632
题目描述
译自 BalticOI 2011 Day1 T3「Switch the Lamp On」
有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会。
有 个这样的元件,你想将其排列成 行 列放在电路板上。电路板的左上角连接电源,右下角连接灯泡。
试求:至少要旋转多少个正方形元件才能让电源与灯泡连通,若无解则输出 。
________________________________________
每一个方格有一对对角线被连接,那么连接的两个连得距离为0,没有连接的两个点的距离为1(需要一次操作可以连通)。
求左上角点到右下角点的最短距离就可以了!
spfa,最好优化一下!
________________________________________
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=503*503+10; 4 const int maxm=503*503*4+10; 5 int t,n,m; 6 struct edge 7 { 8 int u,v,w,nxt; 9 }e[maxm]; 10 int head[maxn],js; 11 void addage(int u,int v,int w) 12 { 13 e[++js].u=u;e[js].v=v;e[js].w=w; 14 e[js].nxt=head[u];head[u]=js; 15 } 16 char s[505]; 17 int dis[maxn]; 18 deque<int>q; 19 bool inq[maxn]; 20 int spfa() 21 { 22 dis[1]=0; 23 memset(inq,0,sizeof inq); 24 inq[1]=1; 25 q.push_back(1); 26 while(!q.empty()) 27 { 28 int u=q.front();q.pop_front();inq[u]=0; 29 for(int i=head[u];i;i=e[i].nxt) 30 { 31 int v=e[i].v; 32 if(dis[v]>dis[u]+e[i].w) 33 { 34 dis[v]=dis[u]+e[i].w; 35 if(!inq[v]) 36 { 37 if(!q.empty()&&dis[v]<=dis[q.front()])q.push_front(v); 38 else q.push_back(v); 39 inq[v]=1; 40 } 41 } 42 } 43 } 44 return dis[(n+1)*(m+1)]; 45 } 46 int main() 47 { 48 49 js=0; 50 memset(head,0,sizeof head); 51 memset(dis,0x3f,sizeof dis); 52 scanf("%d%d",&n,&m); 53 for(int i=0;i<n;++i) 54 { 55 scanf("%s",s); 56 int l=strlen(s)+1; 57 for(int j=0;s[j];++j) 58 { 59 if( s[j]== '\\' ) 60 { 61 int a=i*l+j+1,b=(i+1)*l+j+2; 62 addage(a,b,0);addage(b,a,0); 63 addage(a+1,b-1,1);addage(b-1,a+1,1); 64 } 65 else 66 { 67 int a=i*l+j+2,b=(i+1)*l+j+1; 68 addage(a,b,0);addage(b,a,0); 69 addage(a-1,b+1,1);addage(b+1,a-1,1); 70 } 71 } 72 } 73 int tp=spfa(); 74 if(tp!=0x3f3f3f3f)printf("%d\n",tp); 75 else puts("NO SOLUTION"); 76 77 return 0; 78 }