poj3026

5 篇文章 0 订阅
4 篇文章 0 订阅


题意:就是S去感染A,然后A就变为了S在一起去感染其他的A,转变思路就是迷宫中全都是S,求把他们连起来的最小生成树
具体做法:先建图,然后BFS求出S之间的距离存入map[][]里在求解最小生成树就可以了。

2
6 5
##### 
#A#A##
# # A#
#S  ##
##### 
7 7
#####  
#AAA###
#    A#
# S ###
#     #
#AAA###
#####  

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

//将A与S之间的距离用BFS求出,记录到map中
//需要一个标记数组来标记
public class Main {
	static int leng;
	static int MAX=1<<28;
	static int inc[][]={{1,0},{0,1},{-1,0},{0,-1}};
	static int Maze[][]=new int[110][110];
	static int map[][]=new int[110][110];
	static boolean mark[][]=new boolean[110][110];
	static int x,y;
	class Node
	{
		int x,y;
		int val;
	}
	
	void build()
	{
		Scanner in=new Scanner(System.in);
		int number=in.nextInt();
		while(number--!=0)
		{
			y=in.nextInt();
			x=in.nextInt();
			in.nextLine();
			leng=1;
			for(int i=1;i<=x;i++)
			{
				String data=in.nextLine();
				int len=data.length();
				if(len<y)
				{
					for(int k=1;k<=y-len;k++)
						data+=' ';
				}
				for(int j=1;j<=y;j++)
				{
					if(data.charAt(j-1)=='#')
						Maze[i][j]=-1;
					else if(data.charAt(j-1)=='A'||data.charAt(j-1)=='S')
						Maze[i][j]=leng++;
					else if(data.charAt(j-1)==' ')
						Maze[i][j]=0;
				}
			}
//			for(int i=1;i<=x;i++)
//			{
//				for(int j=1;j<=y;j++)
//				{
//					System.out.print(Maze[i][j]+" ");
//				}
//				System.out.println();	
//			}
			
			
			for(int i=1;i<=x;i++)
			{
				for(int j=1;j<=y;j++)
				{
					Node n=new Node();
					n.x=i;
					n.y=j;
					if(Maze[i][j]>0)
					{
						BFS(n);
					}
				}
			}
			
//			for(int i=1;i<=leng-1;i++)
//			{
//				for(int j=1;j<=leng-1;j++)
//					System.out.print(map[i][j]+" ");
//				System.out.println();
//			}
			prim();
			
		}
	}

void BFS(Node n)
{
	int a=n.x;
	int b=n.y;
	for(int i=1;i<=x;i++)
		for(int j=1;j<=y;j++)
			mark[i][j]=false;
	ArrayList<Node> q=new ArrayList<Node>();
	Node cur;
	n.val=0;
	Node next;
	q.add(n);
	mark[a][b]=true;
	while(!q.isEmpty())
    {
         cur = q.get(0);
         

       for(int i=0; i<4; i++)
        {
    	   next=new Node();
           next.x = cur.x + inc[i][0];
           next.y = cur.y + inc[i][1];

            int temp = Maze[next.x][next.y];

            if((!mark[next.x][next.y]) && temp >= 0)
            {
                
               next.val = cur.val + 1;                
                mark[next.x][next.y] = true;
                q.add(next);

               if(temp > 0)
               {
                     map[Maze[n.x][n.y]][temp] = next.val;
                }
            }
        }
       q.remove(0);
    }
}

void  prim()
{
	int dis[]=new int[110];
	int used[]=new int[110];
	int ans=0;
	int min,now,i,j;
	Arrays.fill(used, 0);
	Arrays.fill(dis, MAX);
	now=1;
	used[now]=1;
	dis[now]=0;
	
	for(i=1;i<leng-1;i++)
	{
		for(j=1;j<=leng-1;j++)//注意此处是小于等于Nodenum
		{
			if(used[j]==0&&dis[j]>map[now][j])
				dis[j]=map[now][j];
		}
		
		min=MAX;
		
		for(j=1;j<=leng;j++)
		{
			if(used[j]==0&&min>dis[j])
				min=dis[now=j];
		}
		used[now]=1;
		ans+=min;
		
	}
	
System.out.println(ans);
}



	public static void main(String[] args) {
		new Main().build();
		
	
	}
	
}


ps:第一次1y排在前十了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值