P9709 [KMOI R1] 军事行动 题解

分析

对于这道题,首先暴力找出任意两座城市之间的最短路,跑 n 次 BFS 就行。这里 BFS 的时候可以直接求第 i 座城市的坐标 (xi,yi) 到所有图上坐标的最短路,最后第 i 座城市到第 j 组城市的最短路就是 (xi,yi)(xj,yj) 的最短路。

现在求出来每两座城市之间的最短路,不难想到题目求的就是这些城市通过连接成树的最小边权和。用 Kruskal 就行。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define re register
#define il inline
#define PII pair<int,pair<int,int>>
#define x first
#define y second

const int N=2001,M=151;
int n,m;
int dx[11]={-1,1,2,-2,-1,1,2,-2},dy[11]={2,2,1,1,-2,-2,-1,-1};
struct node{
	int x,y,id;
}a[N];
int dis[M][M],vis[M][M],dist[N][N];
int fa[N];
struct tree{
	int x,y,z;
}tr[N*N];int idx;

il void bfs(int s){
	memset(vis,0,sizeof(vis));
	memset(dis,0x3f,sizeof(dis));
	queue<PII> qu;
	qu.push({0,{a[s].x,a[s].y}});
	dis[a[s].x][a[s].y]=0;
	while(!qu.empty()){
		PII now=qu.front();qu.pop();
		if(vis[now.y.x][now.y.y]) continue;
		vis[now.y.x][now.y.y]=1;
		for(re int i=0;i<8;++i){
			int x=now.y.x+dx[i],y=now.y.y+dy[i];
			if(x<=0||y<=0||x>m||y>m) continue;
            if(dis[x][y]>now.x+1)
			dis[x][y]=now.x+1,qu.push({now.x+1,{x,y}});
		}
	}
    return ;
}

il bool cmp(tree a,tree b){return a.z<b.z;}
il int find(int x){return (fa[x]==x)?x:(fa[x]=find(fa[x]));}

il void solve(){
	cin>>n>>m;
	for(re int i=1;i<=n;++i) cin>>a[i].x>>a[i].y,a[i].id=i;
	for(re int i=1;i<=n;++i){
		bfs(i);
		for(re int j=1;j<=n;++j) 
            dist[i][j]=dis[a[j].x][a[j].y];
	}
	int ans=0;
	for(re int i=1;i<=n;++i)
		for(re int j=i+1;j<=n;++j)
			tr[++idx]={i,j,dist[i][j]+1};
	sort(tr+1,tr+idx+1,cmp);
	for(re int i=1;i<=n;++i) fa[i]=i;
	for(re int i=1;i<=idx;++i){
		int x=find(tr[i].x),y=find(tr[i].y);
		if(x!=y) ans+=tr[i].z,fa[x]=y;
	}
	cout<<ans;
    return ;
}

signed main(){
	solve();
    return 0;
}
posted @   harmis_yz  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示