普利姆

Agti-Net

/*题意:将所有点连接成有向图,即N个点需要N-1条边,求最短距离
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int dis[1010],book[1010],e[1010][1010];
int a[1010][1010];
int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			if(i==j)
			e[i][j]=0;
			else
			e[i][j]=inf;
		}
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&a[i][j]);
			if(e[i][j]>a[i][j])
			e[i][j]=a[i][j];
		}
		memset(dis,0,sizeof dis);
		memset(book,0,sizeof book);
		for(int i=1;i<=n;i++)
		dis[i]=e[1][i];
		book[1]=1;
		int count=0,sum=0,k;
		while(count<n)
		{
			int min=inf,j;
			for(j=1;j<=n;j++)
			{
				if(!book[j]&&min>dis[j])
				{
					min=dis[j];
					k=j;
				}
			}
			book[k]=1;
			count++;
			sum+=dis[k];
			if(count==n-1)
			break;
			for(int s=1;s<=n;s++)
			if(!book[j]&&dis[s]>e[k][s])
			dis[s]=e[k][s];
		}
		printf("%d\n",sum);
	}
	return 0;
}

Borg Maze
从S出发,吃掉A,每经过一个A就会分裂,求把所有的A吃掉的最少步数

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int e[110][110];
int dis[110],book[110][110];
bool vis[110];
char a[110][110];
int cnt,n,m;
void prim(int v)
{
	for(int i=0;i<n;i++)
	{
		dis[i]=e[v][i];
		vis[i]=0;
	}
	vis[v]=1;
	dis[v]=0;
	for(int i=0;i<n-1;i++)
	{
		int u=-1,ma=inf;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&dis[j]<ma)
			{
				u=j;
				ma=dis[j];
			}
		}
		if(u==-1)
		break;
		vis[u]=1;
		for(int j=0;j<n;j++)
		if(!vis[j]&&dis[j]>e[u][j])
		dis[j]=e[u][j];
	}
}
int x,y;
struct node
{
	int x,y,dis;
	node(int _x=0,int _y=0,int _dis=0):x(_x),y(_y),dis(_dis){}
};
bool use[110][110];
int d[4][2]={0,1,1,0,0,-1,-1,0};
void bfs(int stx,int sty)
{
	node p(stx,sty,0);
	memset(use,false,sizeof use);
	queue<node>q;
	q.push(p);
	use[stx][sty]=1;
	int x1,y1;
	int xx=book[p.x][p.y];
	while(!q.empty())
	{
		p=q.front();
		q.pop();
		if(!(p.x==stx&&p.y==sty))
		{
			if(a[p.x][p.y]=='A'||a[p.x][p.y]=='S')
			{
				int yy=book[p.x][p.y];
				e[xx][yy]=e[yy][xx]=p.dis;
			}
		}
		for(int i=0;i<4;i++)
		{
			x1=p.x+d[i][0];
			y1=p.y+d[i][1];
			if(x1>=0&&x1<x&&y1>=0&&y1<y)
			{
				if(!use[x1][y1]&&a[x1][y1]!='#')
				{
					q.push(node(x1,y1,p.dis+1));
					use[x1][y1]=1;
				}
			}
		}
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	getchar();
	while(t--)
	{
		scanf("%d%d",&y,&x);
		gets(a[0]);
		for(int i=0;i<x;i++)
		gets(a[i]);
		memset(book,-1,sizeof book);
		n=0;
		for(int i=0;i<x;i++)
		for(int j=0;j<y;j++)
		if(a[i][j]=='A'||a[i][j]=='S')
		book[i][j]=n++;
		for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			if(i==j)
			e[i][j]=0;
			else
			e[i][j]=inf;
		}
		for(int i=0;i<x;i++)
		for(int j=0;j<y;j++)
		if(a[i][j]=='A'||a[i][j]=='S')
		bfs(i,j);
		prim(0);
		int res=0;
		for(int i=0;i<n;i++)
		if(dis[i]!=inf)
		res+=dis[i];
		printf("%d\n",res);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值