[最小生成树kruskal]——启动!!!

P3366 【模板】最小生成树

#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pb push_back
#define PII pair<int,pair<int,int> >
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int N = 1e6+5;
int n,m;
int acc[N];
PII va[N];
int find(int x)
{
	if(acc[x]!=x) acc[x] = find(acc[x]);
	return acc[x];
}
void kruskal()
{
	int sum=0,cnt=0;
	for(int i=1;i<=n;i++) acc[i] = i;
	for(int i=1;i<=m;i++)
	{
		int a = va[i].se.fi,b = va[i].se.se,w = va[i].fi;
		int t1 = find(a),t2 = find(b);
		if(t1!=t2)
		{
			acc[t1] = t2;
			sum += w;
			cnt++;
		}
	}
	if(cnt == n-1) cout<<sum;
	else cout<<"orz";
}
signed main()
{
	IOS;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int a,b,c;
		cin>>a>>b>>c;
		va[i] = {c,{a,b}};
	}
	sort(va+1,va+1+m);
	kruskal();
	
}

P1195 口袋的天空

#include<bits/stdc++.h>
//#define int long long
#define fi first
#define se second
#define pb push_back
#define PII pair<int,pair<int,int> >
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int N = 1e6+5;
int n,m,k;
int acc[N];
PII va[N];
int find(int x)
{
	if(acc[x]!=x) acc[x] = find(acc[x]);
	return acc[x];
}
void kurskal()
{
	int cnt = 0,sum =0;
	for(int i=1;i<=n;i++) acc[i] = i;
	for(int i=1;i<=m;i++)
	{
		int a = va[i].se.fi,b =va[i].se.se,w = va[i].fi;
		int t1 = find(a);int t2 = find(b);
		if(t1!=t2)
		{
			acc[t1] = t2;
			sum += w;
			for(int i=1;i<=n;i++)
			{
				if(acc[i]==i) cnt++;
			}
			if(cnt == k)
			{
				cout<<sum;
				return;
			}
			cnt = 0;
		}
	}
	 cout<<"No Answer";
}
signed main()
{
	IOS;
	cin>>n>>m>>k;
	for(int i=1;i<=m;i++)
	{
		int a,b,w;
		cin>>a>>b>>w;
		va[i] = {w,{a,b}};
	}
	sort(va+1,va+1+m);
	kurskal();
}

P2872 [USACO07DEC] Building Roads S

#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pb push_back
#define PII pair<int,int >
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int N = 1e6+5;
int n,m;
int cnt;
double sum=0.0;
struct Node{
	int a;
	int b;
	double w;
}va[N]; //存边 
pair<int,int> spot[N];//存点坐标
int acc[N]; 
bool cmp(Node a,Node b)
{
	return a.w<b.w;
}
int find(int x)
{
	if(acc[x]!=x) acc[x] = find(acc[x]);
	return acc[x];
}
void kruskal()
{
	int t =0;
	for(int i=1;i<=cnt;i++)
	{	
		int x = va[i].a;
		int y = va[i].b;
		double ll = va[i].w;
		int t1 = find(x),t2 = find(y);
		if(t1!=t2)
		{
			acc[t1] = t2;
			sum += ll;
			t++;
			if(t==n-1) break;
		}
		
	}
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) acc[i] = i;
	for(int i=1;i<=n;i++)
	{
		int x,y;
		cin>>x>>y;
		spot[i] = {x,y};
	}
	for(int i=1;i<=m;i++)
	{
		int a,b;
		cin>>a>>b;
		acc[find(a)] = find(b);
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
			int x = abs(spot[i].fi-spot[j].fi);
			int y = abs(spot[i].se-spot[j].se);
			double s = sqrt(x*x*1.0+y*y*1.0);
			cnt++;
			va[cnt].a = i;
			va[cnt].b = j;
			va[cnt].w = s;
		}
	}
	sort(va+1,va+1+cnt,cmp);
	kruskal();
	printf("%.2lf",sum);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值