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;
    }


  • 相关阅读:
    Account group in ERP and its mapping relationship with CRM partner group
    错误消息Number not in interval XXX when downloading
    错误消息Form of address 0001 not designated for organization
    Algorithm类介绍(core)
    梯度下降与随机梯度下降
    反思
    绘图: matplotlib核心剖析
    ORB
    SIFT
    Harris角点
  • 原文地址:https://www.cnblogs.com/01world/p/5651193.html
Copyright © 2011-2022 走看看