首页 > 代码库 > BZOJ2464: 中山市选[2009]小明的游戏

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\n",spfa(num(x1,y1),num(x2,y2)));  140     }141 142     return 0;143 144 } 
View Code

 

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