【杭电多校2020】第二场1001.Total Eclipse(并查集)
程序员文章站
2022-08-15 19:17:19
题目链接思路:按照权值从大到小排序,然后依次加入,并把全场的权值都减到当前权值。用并查集维护连通块的总个数即可。代码:#includeusing namespace std;#define int long long#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);const int N=1e5+7;const int M=4e5+8;const double eps=1...
题目链接
思路:
按照权值从大到小排序,然后依次加入,并把全场的权值都减到当前权值。用并查集维护连通块的总个数即可。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=1e5+7;
const int M=4e5+8;
const double eps=1e-8;
const int mod=1e9+7;
const int inf=0x7fffffff;
const double pi=3.1415926;
int a[N],h[N],e[M],ne[M],f[N],q[N],fa[N],idx;
bool visit[N];
void add(int a,int b)
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
int find(int x)
{
if(x!=f[x])
{
f[x]=find(f[x]);
}
return f[x];
}
int cmp(int x,int y)
{
return a[x]>a[y];
}
signed main()
{
IOS;
int t;
cin>>t;
while(t--)
{
memset(h,-1,sizeof h);
memset(visit,0,sizeof visit);
memset(fa,0,sizeof fa);
int n,m;
cin>>n>>m;
idx=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
f[i]=q[i]=i;
}
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
sort(q+1,q+1+n,cmp);
for(int i=1;i<=n;i++)
{
int u=q[i];
visit[u]=1;
for(int j=h[u];~j;j=ne[j])
{
int k=e[j];
if(!visit[k])
{
continue;
}
int v=find(k);
if(v==u)
{
continue;
}
f[v]=fa[v]=u;
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans+=a[i]-a[fa[i]];
}
cout<<ans<<endl;
}
return 0;
}
本文地址:https://blog.csdn.net/ACkingdom/article/details/107570643
下一篇: iOS 警告消除(记录贴)