[题解]ABC282E Choose Two and Eat One
ABC282E Choose Two and Eat One
又一个图论的回顾——Kruskal最小(最大)生成树算法。
看到\(n\)的范围只有\(500\),应该没有什么特别的算法。那么我们考虑建一个*\(n\)个顶点的完全图,节点\(x\)到节点\(y\)的边权值就是\(x^y+y^x\)。然后跑一遍最大生成树,得到的和就是最大结果了。
如何证明生成树的边一定满足题目条件?因为一共要吃掉\(n-1\)个球,也就是删除图上的\(n-1\)条边,若想让这\(n-1\)条边连接\(n\)个点,必须要求这些边构成一个树。
点击查看代码
#include<bits/stdc++.h> #define int long long using namespace std; struct edge{ int u,v,w; }edges[250010]; int n,m,a[510],fa[510],cnt; bool cmp(edge a,edge b){return a.w>b.w;} int find(int x){ if(fa[x]==x) return x; return fa[x]=find(fa[x]); } int qpow(int a,int b){ int fac=1; while(b){ if(b&1) fac=(fac*a)%m; a=(a*a)%m,b>>=1; } return fac; } signed main(){ cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ edges[++cnt].u=i,edges[cnt].v=j; edges[cnt].w=(qpow(a[i],a[j])+qpow(a[j],a[i]))%m; } } sort(edges+1,edges+1+cnt,cmp); for(int i=1;i<=n;i++) fa[i]=i; int edgecnt=0,ans=0; for(int i=1;i<=cnt;i++){ int u=find(edges[i].u),v=find(edges[i].v); if(u==v) continue; fa[u]=v; edgecnt++; ans+=edges[i].w; if(edgecnt>=n-1) break; } cout<<ans; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效