BZOJ2346:[Baltic 2011]Lamp(最短路)
Description
2255是一个傻X,他连自己家灯不亮了都不知道。
某天TZ大神路过他家,发现了这一情况,
于是TZ开始行侠仗义了。
TZ发现是电路板的问题,
他打开了电路板,发现线路根本没有连上!!
于是他强大的脑力可以使某个格子上的线路从\变为/,
或者从/变为\。
2255不会电路(因为他什么都不会),但是他想知道TZ最少要用多少次脑力才能使他家的灯变亮。
如果无法变亮,输出“NO SOLUTION”。
n,m<=500
Sample Input
3 5
\\/\\
\\///
/\\\\
\\/\\
\\///
/\\\\
Sample Output
1
Solution
考虑当前格子$(i,j)$,若当前格子为$'\'$,那么$(i,j)$到$(i+1,j+1)$的花费为0,$(i+1,j)$到$(i,j+1)$的花费为1.
反之亦然。
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<queue> 5 #define N (2009) 6 #define id(x,y) (x-1)*(m+1)+y 7 using namespace std; 8 9 struct Edge{int to,next,len;}edge[N*N]; 10 struct Node 11 { 12 int num,dis; 13 bool operator < (const Node a) const {return dis>a.dis;} 14 }; 15 int n,m,c,a[N][N],dis[N*N],vis[N*N]; 16 int head[N*N],num_edge; 17 char s[N]; 18 priority_queue<Node>q; 19 20 void add(int u,int v,int l) 21 { 22 edge[++num_edge].to=v; 23 edge[num_edge].next=head[u]; 24 edge[num_edge].len=l; 25 head[u]=num_edge; 26 } 27 28 void Dijkstra(int s) 29 { 30 memset(dis,0x7f,sizeof(dis)); 31 dis[s]=0; q.push((Node){s,0}); 32 while (!q.empty()) 33 { 34 Node x=q.top(); q.pop(); 35 if (vis[x.num]) continue; 36 vis[x.num]=true; 37 for (int i=head[x.num]; i; i=edge[i].next) 38 if (!vis[edge[i].to] && dis[x.num]+edge[i].len<dis[edge[i].to]) 39 { 40 dis[edge[i].to]=dis[x.num]+edge[i].len; 41 q.push((Node){edge[i].to,dis[edge[i].to]}); 42 } 43 } 44 } 45 46 int main() 47 { 48 scanf("%d%d",&n,&m); 49 for (int i=1; i<=n; ++i) 50 { 51 scanf("%s",s); 52 for (int j=1; j<=m; ++j) 53 a[i][j]=(s[j-1]=='\\')?1:0; 54 } 55 for (int i=1; i<=n; ++i) 56 for (int j=1; j<=m; ++j) 57 { 58 if (a[i][j]==1) 59 { 60 add(id(i,j),id(i+1,j+1),0); add(id(i+1,j+1),id(i,j),0); 61 add(id(i+1,j),id(i,j+1),1); add(id(i,j+1),id(i+1,j),1); 62 } 63 else 64 { 65 add(id(i,j),id(i+1,j+1),1); add(id(i+1,j+1),id(i,j),1); 66 add(id(i+1,j),id(i,j+1),0); add(id(i,j+1),id(i+1,j),0); 67 } 68 } 69 Dijkstra(1); 70 if (dis[id(n+1,m+1)]>1e9) puts("NO SOLUTION"); 71 else printf("%d\n",dis[id(n+1,m+1)]); 72 }