题解
传送门 P7528 [USACO21OPEN] Portals G
题意
有
并且可以将一组的传送门消
将一组的四个传送门以任意序交换。
求将所有点连通的最小价值。
首先观察样例的形成图。
不同颜色代表不可互达。
整理一下
将第 1 列名为
第 2 列为
......
于是就有了这样的图。
题意还给了一种方式----交换传送门。
即我们对于第
或
连接
假设对第一组进行交换。
可以明显观察出有两组环进行了合并。
于是可以想到:
对于第
于是代码的总思路就形成了:
以
对于排序后的第
AC 代码如下
#include <bits/stdc++.h> using namespace std; const int N = 1e5+5; int n, m; int ans; int fa[N*2];//并查集 int door[N*2];//门 struct node { int val; int id; } d[N]; bool cmp(node a,node b){ return a.val<b.val; } int root(int x) {//并查集find return fa[x]=fa[x]==x?x:root(fa[x]); } void hb(int a,int b) {//合并两个并查集 fa[root(a)]=root(b); } bool checK(int a,int b) {//看是否在同一并查集 return root(a)==root(b); } signed main() { cin>>n; for(int i=1; i<=2*n; ++i) {//初始化 fa[i]=i; } for(int i=1; i<=n; ++i) { int a,b,c,e; cin>>d[i].val;d[i].id=i; scanf("%d%d%d%d",&a,&b,&c,&e); if(door[a]) hb(door[a],i); if(door[b]) hb(door[b],i); if(door[c]) hb(door[c],i+n); if(door[e]) hb(door[e],i+n); //合并对应的门 door[a]=i; door[b]=i; door[c]=i+n; door[e]=i+n; } sort(d+1,d+n+1,cmp); for(int i=1;i<=n;++i){ if(!checK(d[i].id,d[i].id+n)){ ans+=d[i].val; hb(d[i].id,d[i].id+n); } } cout<<ans; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现