• D. Kilani and the Game(多源BFS)


    题目来源:http://codeforces.com/contest/1105/problem/D

    题意:编号为1-k的点在一张n*m的表格中依次扩散,每个结点有各自的扩散速度且只可以往上下左右四个方向扩散,表格中每个空白的区域只能被一个结点占领,求最后各个结点所占领的区域的数量。

    解题思路:我们可以定义两个队列:que1,que2,que1存放源点的信息,每次取que1中编号相同的结点的信息加入剩余扩散的步数存放入que2中,对que2的结点进行BFS,这样就能保证结点的扩散顺序了。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<stack>
    #include<cstdio>
    #include<map>
    #include<set>
    #include<string>
    #include<queue>
    using namespace std;
    #define inf 0x3f3f3f3f
    typedef long long ll;
    inline ll gcd(ll i,ll j){
        return j==0?i:gcd(j,i%j);
    }
    inline ll lcm(ll i,ll j){
        return i/gcd(i,j)*j;
    }
    const int maxn=1e3+5;
    int vis[maxn][maxn];
    int ans[maxn];
    char mp[maxn][maxn];
    int v[maxn];
    int m,n,p;
    int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    bool jug(int x,int y){
        if(x<0||x>=m||y<0||y>=n||vis[x][y]!=0||mp[x][y]!='.')
        return false;
        return true;
    }
    struct node{
        int x,y,id;
        node(){
            x=y=id=0;
        }
        node(int x,int y,int id):x(x),y(y),id(id){
        }
    };
    struct node1{
        int x,y,wi,id;
        node1(int x,int y,int wi,int id):x(x),y(y),wi(wi),id(id){
        }
        node1(){
            x=y=wi=id=0;
        }
    };
    queue<node> que;
    void bfs(){
        while(!que.empty()){
            node tem=que.front();
            que.pop();
            queue<node1> que1;
            //cout<<tem.id<<endl;
            que1.push(node1(tem.x,tem.y,v[tem.id],tem.id));
            while(!que.empty()&&que.front().id==tem.id){
                que1.push(node1(que.front().x,que.front().y,v[tem.id],tem.id));//找到编号相同的点同时进行扩散
                que.pop();
            }
            while(!que1.empty()){
                node1 tem1;
                tem1=que1.front();
                que1.pop();
                int dx,dy;
                if(tem1.wi<=0){
                    que.push(node(tem1.x,tem1.y,tem1.id));
                    continue;
                }
                for(int i=0;i<4;i++){
                     dx=tem1.x+dir[i][0];
                     dy=tem1.y+dir[i][1];
                    if(jug(dx,dy)){
                        vis[dx][dy]=tem1.id;
                        ans[tem1.id]++;
                        que1.push(node1(dx,dy,tem1.wi-1,tem1.id));
                    }
                }
            }
        }
    }
    int main(){
        scanf("%d%d%d",&m,&n,&p);
        for(int i=1;i<=p;i++){
            scanf("%d",&v[i]);
        }
        for(int i=0;i<m;i++){
            scanf("%s",mp[i]);
        }
        for(int i=1;i<=p;i++){
            for(int j=0;j<m;j++){
                for(int k=0;k<n;k++){
                    if(mp[j][k]==i+'0'){
                        vis[j][k]=i;
                        ans[i]++;
                        que.push(node(j,k,i));//保证结点按顺序扩散
                    }
                }
            }
        }
        bfs();
        /*for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(vis[i][j]==0){
                    cout<<"#"<<" ";
                }
                else
                cout<<vis[i][j]<<" ";
            }
            cout<<endl;
        }*/
        for(int i=1;i<=p;i++){
            cout<<ans[i]<<" ";
        }
        return 0;
    }
  • 相关阅读:
    HttpClient 教程 (四)
    HttpClient 教程 (三)
    HttpClient 教程 (二)
    HttpClient 教程 (一)
    git还原本地提交的某个历史记录
    ExtJS下拉列表使用方法(异步传输数据)
    Struts整合ExtJS
    既有post提交又有get提交时的后台处理办法
    Ajax调用查看页面的后台返回json格式数据
    如何在VS中快速导入新的源码以及文件夹
  • 原文地址:https://www.cnblogs.com/Zhi-71/p/10309354.html
Copyright © 2020-2023  润新知