给定一张包含 个节点和 条无向带权边的图,以及两个序列 分别表示图中的某些节点,定义 为从 到 所有路径各自包含的边权最大值中的最小值,可以任意排列 中的元素,使得 最小化,求出这个最小值。
转化为最小生成树的问题,贪心,在 Kruskal 的过程中额外记录一下每个点集中待匹配的 元素个数,每次连接两个不连通点集 的时候,尽可能多地把 中的 和 中的 匹配,把 中的 和 中的 匹配,代价为:当前边的边权 乘以 匹配数。
首先,需要明确为什么“当前边的边权”是路径中的“边权最大值”。
根据 Kruskal 算法的原理,我们先对边权进行了排序,那么我们一定是按照边权大小升序排序来枚举边。
假设在枚举过程中,当前枚举到了一条权值为 ,可以连接 和 两个未连通点的边,那么我们会选择这条边,并把 所在集合连接起来,所以 到 路径中一定包含了这条边(因为在最后的最小生成树中,任意两节点之间的路径唯一),并且这条边的边权是当前考虑过的所有边中最大的,显然它也是这条路径上最大的。
在之后对边的枚举中,任何选取都不会对 路径产生影响了。
然而这只是一条路径的边权最大值,那么它为什么是 到 所有路径的边权最大值中的“最小值”呢?
采用反证法,记我们在最小生成树的流程中选出来的这条边的边权为 ,假设存在另一条以 为边权最大值的路径,使得 ,那么画个图思考一下会发现,我们根本就不会选择 这条边作为最小生成树的一部分,矛盾,所以假设不成立。
至于为什么要"尽可能多地匹配",这一点从贪心地角度想应该是很明了的,由于 内部是可以取任意顺序的,又因为我们枚举边的顺序是从小到大,无论如何都要做满 次匹配,那肯定是让每一次匹配尽量产生较小的答案,最后的答案一定是最小的。
| #include<bits/stdc++.h> |
| #define int long long |
| using namespace std; |
| int n,m,k; |
| const int N=2e5+10; |
| struct Edge |
| { |
| int u,v,w; |
| const bool operator <(Edge tmp)const{return w<tmp.w;} |
| }e[N]; |
| int a[N],b[N]; |
| int fa[N]; |
| int siza[N],sizb[N]; |
| inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} |
| signed main() |
| { |
| ios::sync_with_stdio(0); |
| cin.tie(0),cout.tie(0); |
| cin>>n>>m>>k; |
| for(int i=1,u,v,w;i<=m;++i) |
| { |
| cin>>u>>v>>w; |
| e[i]={u,v,w}; |
| } |
| for(int i=1;i<=k;++i)cin>>a[i],siza[a[i]]++; |
| for(int i=1;i<=k;++i)cin>>b[i],sizb[b[i]]++; |
| for(int i=1;i<=n;++i)fa[i]=i; |
| sort(e+1,e+m+1); |
| int ans=0; |
| for(int i=1;i<=m;++i) |
| { |
| int fx=find(e[i].u),fy=find(e[i].v); |
| if(fx==fy)continue; |
| int w=e[i].w; |
| int mn=min(siza[fx],sizb[fy]); |
| ans+=w*mn,siza[fx]-=mn,sizb[fy]-=mn; |
| |
| mn=min(sizb[fx],siza[fy]); |
| ans+=w*mn,sizb[fx]-=mn,siza[fy]-=mn; |
| |
| fa[fx]=fy; |
| siza[fy]+=siza[fx],sizb[fy]+=sizb[fx]; |
| siza[fx]=0,sizb[fx]=0; |
| |
| } |
| cout<<ans; |
| return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效