zoukankan      html  css  js  c++  java
  • BZOJ2464: 中山市选[2009]小明的游戏

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

    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。


    题解Here!
    本来以为是什么$DP$神题。。。
    看完题发现这就是一道最短路沙茶题。。。
    $Spfa$不多说。。。
    记得清零。。。
    附代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define MAXN 250010
    #define MAXM 510
    #define MAX 999999999
    using namespace std;
    const int fx[4]={1,-1,0,0},fy[4]={0,0,1,-1};
    int n,m,s,t,c=1;
    char g[MAXM][MAXM];
    int head[MAXN],path[MAXN];
    bool vis[MAXN];
    struct Graph{
        int next,to,w;
    }a[MAXN<<3];
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    inline int id(int x,int y){return (x-1)*m+y;}
    inline bool check(int x,int y){
        if(x<1||x>n||y<1||y>m)return true;
        return false;
    }
    inline int relax(int u,int v,int w){
        if(path[v]>path[u]+w){
            path[v]=path[u]+w;
            return 1;
        }
        return 0;
    }
    inline void add(int u,int v,int w){
        a[c].to=v;a[c].w=w;a[c].next=head[u];head[u]=c++;
    }
    void spfa(){
        int u,v;
        queue<int> q;
        for(int i=1;i<=n*m;i++){path[i]=MAX;vis[i]=false;}
        path[s]=0;
        vis[s]=true;
        q.push(s);
        while(!q.empty()){
            u=q.front();
            q.pop();
            vis[u]=false;
            for(int i=head[u];i;i=a[i].next){
                v=a[i].to;
                if(relax(u,v,a[i].w)&&!vis[v]){
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
        printf("%d
    ",path[t]);
    }
    void init(){
        int u,v,w;
        c=1;
        memset(head,0,sizeof(head));
        for(int i=1;i<=n;i++)scanf("%s",g[i]+1);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            u=id(i,j);
            for(int k=0;k<4;k++){
                if(check(i+fx[k],j+fy[k]))continue;
                v=id(i+fx[k],j+fy[k]);w=(g[i][j]==g[i+fx[k]][j+fy[k]]?0:1);
                add(u,v,w);
            }
        }
        u=read()+1;v=read()+1;
        s=id(u,v);
        u=read()+1;v=read()+1;
        t=id(u,v);
    }
    int main(){
        while(1){
            n=read();m=read();
            if(n==0&&m==0)break;
            init();
            spfa();
        }
        return 0;
    }
    
  • 相关阅读:
    批处理
    使用T-SQL语句更新数据、删除
    使用T-SQL语句一次性插入另一张表的数据
    使用T-SQL语句插入数据
    CSS色调旋转滤镜
    初探Lerna
    基层管理人员的部分思考 --读《大秦帝国》有感
    (转)React学习笔记(干货满满)
    git常用命令(转)
    个人JS体系整理(三)
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9478527.html
Copyright © 2011-2022 走看看