poj3026

題意:給一個迷宮,S,A,空格都可以走,問以最短步數走完全部S和A的最短路,把S和A看成點,先分別求出兩兩最短路,然後求最小生成樹。

#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <stack>
#include <iomanip>
using namespace std;
int w[102][102],node[55][55],n,m,cnt,dis[102][102];
char mapp[55][55];
 bool visit[55][55];
int dre[4][2]={1,0,0,1,-1,0,0,-1};
const int inf=1000000;
struct point
{
    int x,y,num;
};
void bfs(int x,int y)
{
    memset(visit,0,sizeof(visit));
    queue<point>q;
    point p;
    p.x=x;
    p.y=y;
    p.num=node[x][y];
    q.push(p);
    visit[x][y]=1;
    memset(dis,inf,sizeof(dis));
    dis[p.x][p.y]=0;
    while(!q.empty())
    {
        point temp=q.front();
        q.pop();
        if(temp.num)
            w[p.num][temp.num]=dis[temp.x][temp.y];
        for(int i=0;i<4;i++)
        {
            int ix=temp.x+dre[i][0];
            int iy=temp.y+dre[i][1];
            if(ix<0||ix>=n||iy<0||iy>=m)continue;
           if(!visit[ix][iy]&&mapp[ix][iy]!='#')
        {
            dis[ix][iy]=dis[temp.x][temp.y]+1;
            point cur;
            cur.x=ix;
            cur.y=iy;
            cur.num=node[ix][iy];
            q.push(cur);
            visit[ix][iy]=1;
        }
        }
    }
    return ;
}
int prim()
{
    int zx[102];
    memset(zx,0,sizeof(zx));
    int low_dis[102];
    memset(low_dis,inf,sizeof(low_dis));
    int len=0,sum=1;
    int len1,p;
    int s=1;
    zx[s]=1;
    while(sum!=cnt)
    {
        len1=inf;
        for(int j=2;j<=cnt;j++)
        {
            if(!zx[j]&&w[s][j]<low_dis[j])
            {
                low_dis[j]=w[s][j];
            }
            if(!zx[j]&&len1>low_dis[j])
            {
                len1=low_dis[j];
                p=j;
            }
        }
        s=p;
        zx[s]=1;
        sum++;
        len+=len1;
    }
    return len;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>m>>n;
        char temp[55];
        gets(temp);
        cnt=0;
        memset(node,0,sizeof(node));
        for(int i=1;i<=n;i++)
        {
          gets(mapp[i]);
            for(int j=1;j<=m;j++)
           {
               if(mapp[i][j]=='S'||mapp[i][j]=='A')
               {
                  node[i][j]=++cnt;
               }
           }
        }
           for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(node[i][j])
            bfs(i,j);
       cout<<prim()<<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章