abc270F - Transportation

发布时间 2023-10-14 23:46:38作者: gan_coder

F - Transportation
一天遇到两道生成树的题目,还都不会做,菜哭的一天。

这题的做法是另外建两个点n+1,n+2,然后做生成树,因为我们只要前n个点联通就行,后面两个点不一定,那么枚举一下就行。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#define A puts("YES")
#define B puts("NO")
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (int (i)=(b);(i)>=(a);(i)--)
#define mk(x,y) make_pair((x),(y))
using namespace std;
typedef double db;
typedef long long ll;
const int N=2e5+5;
const ll inf=1ll<<60;
struct node{
	ll x,y,v;
};
node e[N*3];

ll tot;
ll x[N],y[N];
ll a[N],b[N],c[N],n,m,f[N],s[N],f1,f2,ans=inf;
bool cmp(node a,node b){
	return a.v<b.v;
}
ll find(ll x){
	if (x==f[x]) return x;
	return f[x]=find(f[x]);
}
void work(){
	sort(e+1,e+tot+1,cmp);
	
	fo(i,1,n+2) f[i]=i,s[i]=1;
	
	ll sum=0;
	fo(i,1,tot) {
		f1=find(e[i].x);
		f2=find(e[i].y);
		if (f1^f2){
			f[f1]=f2;
			s[f2]+=s[f1];
			sum+=e[i].v;
		}
	}
	
	f1=find(1);
	if (s[f1]>=n) ans=min(ans, sum);
}
int main()
{ 
//	freopen("data.in","r",stdin);	
//	freopen("data.out","w",stdout);

	
	scanf("%lld %lld",&n,&m);
	fo(i,1,n) scanf("%lld",&x[i]);
	fo(i,1,n) scanf("%lld",&y[i]);
	fo(i,1,m) {
		scanf("%lld %lld %lld",&a[i],&b[i],&c[i]);
	}
	
	fo(s,0,3) {
		tot=0;
		if (s&1) fo(i,1,n) e[++tot]=(node){i,n+1,x[i]};
		if (s&2) fo(i,1,n) e[++tot]=(node){i,n+2,y[i]};
		fo(i,1,m) e[++tot]=(node){a[i],b[i],c[i]};
		
		work();
	}
	
	printf("%lld",ans);

	return 0;
}