题意
主要就是每次操作删去一个数,知道最后只剩下一个数了
思路
竟然是最大生成树
每次删去一个点,也就相当于将两个点进行合并了,其实也不用管是将那个点删去了反正是合并了。
n个点,刚好可以合并n-1次,也就是每次找未合并的最大边就可以了
ps:竟然能将这里联系起来,思维还是不够强呀。
生成树:每次将树扩大一点,也就相当于可选的少了一个点,或者说是树上多了一个点,只需要n-1次操作
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int M=505;
int n,mod,a[M];
int kpow(int a,int b) {
int ans=1;
while(b) {
if(b&1)ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
int calc(int x,int y) {
return (kpow(x,y)+kpow(y,x))%mod;
}
int fa[M];
int find(int x) {
return x==fa[x]?fa[x]:fa[x]=find(fa[x]);
}
struct node {
int u,v,w;
bool operator<(const node T)const {
return w>T.w;
}
};
vector<node>v;
signed main() {
cin>>n>>mod;
for(int i=1;i<=n;i++)cin>>a[i],fa[i]=i;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
v.push_back({i,j,calc(a[i],a[j])});
sort(v.begin(),v.end());
int ans=0;
for(auto [x,y,w]:v) {
int fx=find(x),fy=find(y);
if(fx==fy)continue;
fa[fx]=fy;
ans+=w;
}
cout<<ans;
return 0;
}
标签:abc,fa,--,kpow,int,ans,282,mod
From: https://www.cnblogs.com/basicecho/p/16991213.html