• 欢迎光临~

abc--282--E

开发技术 开发技术 2022-12-18 次浏览

题意

主要就是每次操作删去一个数,知道最后只剩下一个数了

思路

竟然是最大生成树
每次删去一个点,也就相当于将两个点进行合并了,其实也不用管是将那个点删去了反正是合并了。
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--282--E
喜欢 (0)