BZOJ2464: 中山市选[2009]小明的游戏

2464: 中山市选[2009]小明的游戏

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 280  Solved: 124
[Submit][Status]

Description

小 明最近喜欢玩一个游戏。给定一个n * m的棋盘,上面有两种格子#和@。游戏的规则很简单:给定一个起始位置和一个目标位置,小明每一步能向上,下,左,右四个方向移动一格。如果移动到同一类 型的格子,则费用是0,否则费用是1。请编程计算从起始位置移动到目标位置的最小花费。

Input

    输入文件有多组数据。
    输入第一行包含两个整数n,m,分别表示棋盘的行数和列数。
    输入接下来的n行,每一行有m个格子(使用#或者@表示)。
    输入接下来一行有四个整数x1, y1, x2, y2,分别为起始位置和目标位置。
当输入n,m均为0时,表示输入结束。

Output

    对于每组数据,输出从起始位置到目标位置的最小花费。每一组数据独占一行。

Sample Input

2 2
@#
#@
0 0 1 1
2 2
@@
@#
0 1 1 0
0 0

Sample Output

2
0

HINT

对于100%的数据满足:1 < = n, m <= 500

Source

题解:
对于这种题目我只能说呵呵。。。
裸最短路吧,连spfa都不卡。。。
代码:
  1 #include<cstdio>
  2 
  3 #include<cstdlib>
  4 
  5 #include<cmath>
  6 
  7 #include<cstring>
  8 
  9 #include<algorithm>
 10 
 11 #include<iostream>
 12 
 13 #include<vector>
 14 
 15 #include<map>
 16 
 17 #include<set>
 18 
 19 #include<queue>
 20 
 21 #include<string>
 22 
 23 #define inf 1000000000
 24 
 25 #define maxn 1000000+5
 26 
 27 #define maxm 1000000
 28 
 29 #define eps 1e-10
 30 
 31 #define ll long long
 32 
 33 #define pa pair<int,int>
 34 
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36 
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38 
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40 
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42 
 43 #define mod 1000000007
 44 #define num(i,j) ((i-1)*m+j)
 45 
 46 using namespace std;
 47 
 48 inline int read()
 49 
 50 {
 51 
 52     int x=0,f=1;char ch=getchar();
 53 
 54     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 55 
 56     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 57 
 58     return x*f;
 59 
 60 }
 61 struct edge{int go,next,w;}e[2*maxn];
 62 
 63 int n,m,k,s,t,a[maxn],tot,d[maxn],head[maxn];
 64 
 65 bool v[maxn];
 66 queue<int>q;
 67 char st[maxn];
 68 const int dx[4]={0,1,0,-1};
 69 const int dy[4]={1,0,-1,0};
 70 
 71 void insert(int x,int y,int z)
 72 
 73 {
 74 
 75     e[++tot].go=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
 76 
 77 }
 78 
 79 int spfa(int s,int t)
 80 
 81 {
 82 
 83     for(int i=1;i<=n*m;++i)d[i]=inf;
 84 
 85     memset(v,0,sizeof(v));
 86 
 87     d[s]=0;q.push(s);
 88 
 89     while(!q.empty())
 90 
 91     {
 92 
 93         int x=q.front();q.pop();v[x]=0;    
 94 
 95         for(int i=head[x],y;i;i=e[i].next)
 96 
 97          if(d[x]+e[i].w<d[y=e[i].go])
 98 
 99          {
100 
101              d[y]=d[x]+e[i].w;
102 
103              if(!v[y]){v[y]=1;q.push(y);}
104 
105          }
106 
107     }
108     return d[t];
109 
110 }
111 
112 int main()
113 
114 {
115 
116     freopen("input.txt","r",stdin);
117 
118     freopen("output.txt","w",stdout);
119 
120     while(1)
121     {
122         n=read(),m=read();
123         if(n*m==0)break;
124         memset(head,0,sizeof(head));tot=0;
125         for1(i,n)
126         {
127             scanf("%s",st+1);
128             for1(j,m)a[num(i,j)]=st[j]=='#'?0:1;
129         }
130         for1(i,n)
131          for1(j,m)
132           for0(k,3)
133           {
134               int ii=i+dx[k],jj=j+dy[k];
135               if(ii<1||ii>n||jj<1||jj>m)continue;
136               insert(num(i,j),num(ii,jj),a[num(i,j)]!=a[num(ii,jj)]);
137           }
138         int x1=read()+1,y1=read()+1,x2=read()+1,y2=read()+1;
139         printf("%d
",spfa(num(x1,y1),num(x2,y2)));  
140     }
141 
142     return 0;
143 
144 } 
View Code
原文地址:https://www.cnblogs.com/zyfzyf/p/4121581.html