欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Out of Hay最小生成树

程序员文章站 2022-06-16 08:58:12
...

Out of Hay
原题链接https://vjudge.net/contest/352170#problem/D
Out of Hay最小生成树
Out of Hay最小生成树
题意为给出n个地点之间的m条路,计算链接到所以地点的最短的路中最长的一截的长度。相较于板子,增加一步判断大小,选择最大的一条路即可。
Prim:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
long long map[3005][3005];
long long dis[300005];
bool vis[300005];
long long ans;
long long n;
long long maxx;
void prim()
{
    ans = 0;
    long long i, j;
    for (i = 1; i <= n; i++)
    {
        dis[i] = map[1][i];
        vis[i] = false;
    }
    vis[1] = true;
    for (i = 0; i < n - 1; i++)
    {
        long long minn = INF;
        long long p = 1;
        for (j = 1; j <= n; j++)
        {
            if (!vis[j] && dis[j] < minn)
            {
                minn = dis[j];
                p = j;
            }
        }
        // cout << "***" << endl;
        //  for (j = 1; j <= n; j++)
        //  {
        //      cout << dis[j] << " ";
        //   }
        //    cout << endl;
        if (minn == INF)
        {
            ans = -1;
            return;
        }
        ans += minn;
        maxx = max(maxx, minn);//选取我们选的路中最大的一条。
        vis[p] = true;
        for (j = 1; j <= n; j++)
        {
            if (!vis[j] && dis[j] > map[p][j])
            {
                dis[j] = map[p][j];
            }
        }
    }
    return;
}
int main()
{
    long long m;
    long long i, j;
    scanf("%lld %lld", &n, &m);
    for (i = 0; i <= n; i++)
    {
        for (j = 0; j <= n; j++)
        {
            map[i][j] = INF;
        }
    }
    while (m--)
    {
        long long a, b, w;
        scanf("%lld %lld %lld", &a, &b, &w);
        if (w < map[a][b])//尤其要注意读取地图只要最小的一条路,因为这个wa了3发,Emmmm.
        {
            map[a][b] = w;
        }
        if (map[b][a] > w)
        {
            map[b][a] = w;
        }
    }
    maxx = -1;
    prim();
    cout << maxx << endl;
    return 0;
}

Kruskal:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <queue>
using namespace std;
long long pre[300005];
long long map[3005][3005];
struct node
{
	long long u;
	long long v;
	long long w;
} stu[300005];
long long ans;
long long cnt;
long long maxx;
bool cmp(node x, node y)
{
	return x.w < y.w;
}
long long find(long long x)
{
	if (x == pre[x])
	{
		return x;
	}
	return pre[x] = find(pre[x]);
}
void join(long long x, long long y, long long w)
{
	long long ss1 = find(x);
	long long ss2 = find(y);
	if (ss1 != ss2)
	{
		pre[ss2] = ss1;
		ans += w;
		maxx = max(maxx, w);//选取最长的一条路。
		cnt--;
	}
}
int main()
{
	long long n, i, m;
	scanf("%lld %lld", &n, &m);
	ans = 0;
	cnt = n;
	for (i = 0; i <= n; i++)
	{
		pre[i] = i;
	}
	for (i = 0; i < m; i++)
	{
		scanf("%lld %lld %lld", &stu[i].u, &stu[i].v, &stu[i].w);
	}
	sort(stu, stu + m, cmp);
	/*	for (i = 0; i < k; i++)
	{
		printf("*%lld %lld %lld\n", stu[i].u, stu[i].v, stu[i].w);
	}
	for (i = 0; i <= n;i++)
	{
		cout << pre[i] << endl;
	}
		cout << endl;*/
	maxx = -1;
	for (i = 0; i < m; i++)
	{
		join(stu[i].u, stu[i].v, stu[i].w);
		if (cnt == 1)
		{
			break;
		}
	}
	if (cnt > 1)
	{
		ans = -1;
	}
	cout << maxx << endl;
	return 0;
}
相关标签: 最小生成树