zoukankan      html  css  js  c++  java
  • poj3026 bfs+prim

    题意:

    有一个n*m的图,有S,A,#和空格,S可以到达A并且使A变成S,然后这个S又可以去侵染别的A,问A都变成S需要多少步?

    分析:

    题目相当于求出S和A构成的最小生成树。首先把S和A找出来,枚举每个S和A,然后bfs求一下单点到其他点的最短距离,然后套prim模板就行。

    这题有个特别坑的地方就是数字后面可等有多个空格,好坑!!!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<stack>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define mp make_pair
    const int INF=1000000000;
    const int N=500+9;
    typedef pair<int,int>pii; //点的坐标 <x,y>
    typedef pair<int,pii>piii; //<步数,点>
    int w[N][N],low[N];
    bool vis[N][N];
    char s[N][N];
    int n,m;
    int dx[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    vector<pii>vec; //存S和A
    map<pii,int>id; //给每个S和A编一个号
    int sid;
    void bfs(pii start)
    {
        queue<piii>q;
        memset(vis,0,sizeof(vis));
        q.push(mp(0,start));
        vis[start.first][start.second]=1;
        while(!q.empty()){
            piii p=q.front();q.pop();
            int step=p.first,x=p.second.first,y=p.second.second;
            for(int i=0;i<4;i++){
                int xx=x+dx[i][0],yy=y+dx[i][1];
                if(xx<0||yy<0||xx==n||yy==m||vis[xx][yy])continue;
                vis[xx][yy]=1;
                if(s[xx][yy]=='A'||s[xx][yy]=='S'){
                    w[id[mp(xx,yy)]][sid]=step+1;continue;
                }
                if(s[xx][yy]==' ')q.push(mp(step+1,mp(xx,yy)));
            }
        }
    }
    int prim(int n)
    {
        bool vis[111];
        memset(vis,0,sizeof(vis));
        vis[0]=1;
        int ans=0,p=0;
        for(int i=0;i<n;i++)low[i]=w[p][i];
        for(int i=1;i<n;i++){
            int minn=INF;
            for(int j=0;j<n;j++)if(!vis[j]&&minn>low[j])minn=low[p=j];
            ans+=minn;
            vis[p]=1;
            for(int j=0;j<n;j++)if(!vis[j]&&low[j]>w[p][j])low[j]=w[p][j];
        }
        return ans;
    }
    int main()
    {
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d%d",&m,&n);
            vec.clear();
            id.clear();
            gets(s[0]); //注意可能有多个空格
            for(int i=0;i<n;i++){
                gets(s[i]);
                for(int j=0;j<m;j++)
                    if(s[i][j]=='A'||s[i][j]=='S')id[mp(i,j)]=vec.size(),vec.push_back(mp(i,j));
            }
      
            for(int i=0;i<vec.size();i++)for(int j=0;j<vec.size();j++)w[i][j]=i==j?0:INF;
            for(int i=0;i<vec.size();i++){
                sid=id[vec[i]];
                bfs(vec[i]);
            }
            printf("%d
    ",prim(vec.size()));
        }
        return 0;
    }


  • 相关阅读:
    WampServer软件
    ASP.NET Core中返回 json 数据首字母大小写问题
    区块链的入门与应用(1)
    阿里云oss 的坑==》 路径有区分大小写
    uni-app 学习笔记 小于号问题
    uni-app 学习笔记-引用外部js并调用
    net core 简单读取json配置文件
    net core 3 使用 autofac
    js 获取对应的url参数
    postman 跟restsharp 模拟请求http
  • 原文地址:https://www.cnblogs.com/01world/p/5651193.html
Copyright © 2011-2022 走看看