AtCoder Beginner Contest 065(CD)

tech2022-10-22  122

AtCoder Beginner Contest 065(CD)

C - Reconciled?

思路: n , m n,m n,m等价,可假设 n ≤ m n\le m nm

分情况讨论:

1. n = = m 1.n==m 1.n==m

a n s = 2 ( A n n ) 2 ans=2(A_n^n)^2 ans=2(Ann)2

2. n = m − 1 n=m-1 n=m1

a n s = A n n × A m m ans=A_{n}^{n}\times A_{m}^m ans=Ann×Amm

3. n < m n<m n<m

a n s = 0 ans=0 ans=0

D - Built?

思路:最小生成树。

显然直接暴力加所有边。

考虑对按 x x x排序后。

若三个点 A , B , C A,B,C A,B,C

A , B A,B A,B连边 x b − x a x_b-x_a xbxa B , C B,C B,C连边 x c − x b x_c-x_b xcxb

A , C A,C A,C不用再连边 x c − x a x_c-x_a xcxa

同理:不用连 y c − y a y_c-y_a ycya

综上只用连相邻的 x b − x a , y b − y a x_b-x_a,y_b-y_a xbxa,ybya

然后对这 2 ( n − 1 ) 2(n-1) 2(n1)条边进行排序, k r u s k a l kruskal kruskal即可。

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7; #define mst(a,b) memset(a,b,sizeof a) #define lx x<<1 #define rx x<<1|1 #define reg register #define PII pair<int,int> #define fi first #define se second #define pb push_back #define il inline int r[N]; struct edge{ int u,v,w; bool operator<(const edge& e)const{ return w<e.w; } }e[N<<1]; struct point{ int x,y,id; }a[N]; bool cmp1(point a,point b){ return a.x<b.x; } bool cmp2(point a,point b){ return a.y<b.y; } int find(int x){ return r[x]==x?x:r[x]=find(r[x]); } int main(){ int n;cin>>n; for(int i=1;i<=n;i++){ cin>>a[i].x>>a[i].y; a[i].id=r[i]=i; } sort(a+1,a+n+1,cmp1); int s=0; for(int i=2;i<=n;i++){ e[s++]={a[i-1].id,a[i].id,a[i].x-a[i-1].x}; } sort(a+1,a+n+1,cmp2); for(int i=2;i<=n;i++){ e[s++]={a[i-1].id,a[i].id,a[i].y-a[i-1].y}; } sort(e,e+s); int tot=0; ll ans=0; for(int i=0;i<s;i++){ int u=e[i].u,v=e[i].v; u=find(u),v=find(v); if(u!=v){ r[u]=v; tot++; ans+=e[i].w; } if(tot==n-1) break; } cout<<ans<<endl; return 0; }
最新回复(0)