0
点赞
收藏
分享

微信扫一扫

最小生成树(prim算法 和 kruskal算法)

东方小不点 2022-04-14 阅读 64
图论

例题:【模板】最小生成树 - 洛谷

prim算法

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<unordered_map>
#define x first
#define y second 
#define _for(i,s,t) for(int i = (s);i <=t ; i++)
#define FAST ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);

using namespace std;

typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int,int> PII;

const int N = 5010,INF = 0x3f3f3f3f;


int dist[N];
bool st[N];
int g[N][N];

int n,m;

int prim()
{
	memset(dist , 0x3f , sizeof dist); //初始化所有点的距离为无穷;
	 
	int res = 0 ;
	
	for(int i =0 ;i< n ; i++) //进行 n 次迭代 
	{
		int t = -1; //代表我们每次选择的点 
		
		for(int j = 1; j <= n ;j ++) //选出一个到当前集合距离最近的一个点 
		{
			if(!st[j] && (t == -1 || dist[t] > dist[j])) 
				t = j;
		}
		
		//如果这个点不是第一个点 and 这个点的距离是无穷 ,代表我们当前这个图不连通 
		if( i && dist[t] == INF) return INF;
		
		if(i) res += dist[t];  //记录答案 
		
		for(int j = 1;j <= n ;j++) //更新所有点到当前集合的距离 
		{
			dist[j] = min(dist[j] , g[t][j]);
		}
		
		st[t] = true;
	}
	
	return res;
}

int main()
{
	scanf("%d%d",&n,&m);
	
	memset(g ,0x3f ,sizeof g);

	_for(i,1,m)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		g[a][b] = g[b][a] = min(g[a][b],c);
	}
	
	int t = prim();
	
	if(t == INF) puts("orz");
	else printf("%d",t);
	
	return 0;
}

kruskal算法 

前置知识:并查集(C++)_是饿梦啊的博客-CSDN博客

#include<iostream>
#include<cstring>
#include<algorithm>
#include<unordered_map> 

using namespace std;

const int N =200010;

struct Edge
{
    int a,b,w;
    
    bool operator< (const Edge &W)const
    {
        return w < W.w;
    }
}edges[N];

int p[N];
int n,m;

int find(int x)
{
    if(x != p[x]) p[x] = find(p[x]);
    return p[x];
}


int main()
{
    scanf("%d%d",&n,&m);
    
    for(int i =0 ;i < m ;i ++)
    { 
        int a,b,w;
        scanf("%d%d%d", &a, &b, &w);
        edges[i] = {a,b,w};
     }
    
    sort(edges,edges + m);
    
    for(int i =1 ;i<= n ;i++) p[i] = i;
    
    int res =0 , cnt = 0;
    
    for(int i =0 ;i< m ;i++)
    {
        int a = edges[i].a , b = edges[i].b , w = edges[i].w;
        
        a = find(a), b = find(b);
        if(a != b)
        {
            p[a] = b;
            cnt ++;
            res += w;
        }
    }
    
    if(cnt < n - 1) puts("orz");
    else printf("%d",res);
    
    return 0;
}

 拆地毯 - 洛谷

#include<iostream>
#include<cstring>
#include<cmath>
#include<unordered_map>
#include<queue>
#include<map>
#include<algorithm>
#define x first
#define y second
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
 
const int N = 100010;

int n,m,k,res,cnt;
int p[N];

struct Edge
{
	int a,b,w;
	bool operator < (const Edge &W)const
	{
		return w > W.w;
	}
}edges[N];

int find(int x)
{
	if(x!= p[x]) p[x] = find(p[x]);
	return p[x];
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	LL sum = 0;
	
	for(int i = 1 ;i <= m  ;i++)
	{
		int a,b,v;
		scanf("%d%d%d",&a,&b,&v);
		edges[i] = {a,b,v};
	}
	
	for(int i = 1;i <= n ;i++) p[i] = i;
	sort(edges + 1, edges + m + 1);
	
	for(int i = 1 ;i<= m; i++)
	{
		if(cnt >= k) break;
		
		int a = edges[i].a , b = edges[i].b , w = edges[i].w;
		
		a = find(a), b = find(b);
		if(a != b)
		{
			p[a] = b;
			if(cnt <= k)res += w,cnt ++;
		}
	}
	
	printf("%lld",res);
	return 0;
}
/*还得是自己写的测试数据啊
9 10 4
1 2 10
1 3 9
2 3 7
4 5 3
2 4 9
3 5 8
6 7 5
6 5 8
7 8 10
8 9 10
*/

口袋的天空 - 洛谷

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
 
using namespace std;

const int N = 100010;
typedef long long LL;
typedef pair<int, int> PII;

int n,m,k;
int p[N];

struct Edge 
{
	int a, b, w;
	bool  operator < (const Edge &W)const
	{
		return w < W.w;
	}
}edges[N];

int find(int x)
{
	if (x != p[x]) p[x] = find(p[x]);
	return p[x];
}

int main()
{
	scanf("%d%d%d", &n, &m, &k);
	
	for (int i = 1; i <= m; i++)
	{
		int a, b, w;
		scanf("%d%d%d", &a, &b, &w);
		edges[i] = {a,b,w};
	}

	sort(edges + 1, edges + m + 1);

	for (int i = 1; i <= n; i++) p[i] = i;

	int res = 0,cnt = 0;

	for (int i = 1; i <= m ; i++)
	{
		int a = edges[i].a, b = edges[i].b, w = edges[i].w;

		a = find(a) , b = find(b);
		if (a != b)
		{
			p[a] = b;
			res += w;
			cnt++;
		}
		
		if(cnt == n - k)
		{
			printf("%d",res);
			return 0;
		}	
	}
	
	printf("No Answer");

	return 0;
}
举报

相关推荐

0 条评论