hdu_1875_畅通工程再续 prim和kruskal

这个题是个典型的最小生成树的题目,但是刚开始怎么都过不了,后来发现两种写法都有疏忽,但是prim的到目前为止不懂为什么刚开始的不对,kruskal算法,并查集的初始条件从0开始写成从1开始了,所以已知wa,还有这个题比最小生成树一个卡点就是处理两点之间的距离的时候,要保证点都在10-1000之间。其它的没有什么坑了。

代码一(prim)

#include <stdio.h>
#include <string.h>
#include <math.h>
#define INFI 999999999.0

using namespace std;
const int N = 130;
typedef struct point
{
    int x, y;
}point;
double Map[N][N];
point p[N];
int vis[N];
double ans;
double low_cost[N];
double calc(int a, int b)
{
    return sqrt((p[b].y - p[a].y) * (p[b].y - p[a].y) + (p[b].x - p[a].x) * (p[b].x - p[a].x));
}
void calc_distance(int n)
{
    memset(Map, 0, sizeof(Map));
    double t;
    for (int i = 0; i < n; i++)
    {
        for (int j = i + 1; j < n; j++)    
        {
            t = calc(i, j);
            if (t >= 10 && t <= 1000)
                Map[i][j] = Map[j][i] =calc(i, j);
            else
                Map[i][j] = Map[j][i] = INFI;
        }
            
    }
}
int prim(int n)
{
    for (int i = 0; i < n; i++)
        low_cost[i] = Map[0][i];
    vis[0] = 1;
    for (int i = 1; i < n; i++)
    {
        int k = 0;
        double min = INFI;
        for (int j = 1; j < n; j++)
        {
            if (!vis[j] && min > low_cost[j])
            {
                min = low_cost[j];
                k = j;
            }
        }
        if (k != 0)
        {
            vis[k] = 1;
            ans += min;
        }
        else
            return 0;
        for (int j = 1; j < n; j++)
        {
            if (!vis[j] && Map[k][j] < low_cost[j])
                low_cost[j] = Map[k][j];
        }
    }
    return 1;
}
int main()
{
    int T, C;
    scanf("%d", &T);
    while (T--)
    {
        memset(vis, 0, sizeof(vis));
        ans = 0.0;
        scanf("%d", &C);
        for (int i = 0; i < C; ++i)
            scanf("%d %d", &p[i].x, &p[i].y);
        calc_distance(C);
        int t = prim(C);
        if (t == 0)
        {
            puts("oh!");
            continue;
        }
        ans *= 100.0;
        printf("%.1f
", ans);
    }
    return 0;
}
View Code

代码二(kruskal)

#include<iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define EPS 1e-10
using namespace std;
struct Point{
    int x, y;
};
struct edge{
    int s, e;
    double dis;
};
const int N = 123;
int father[N], num[N];
Point p[N];
edge E[N * N / 2];
double ans = 0.0;
void init(int n)
{
    for (int i = 0; i <= n; ++i)
    { 
        father[i] = i;
        num[i] = 1;
    }
}
double calct(int a, int b)
{
    return sqrt((p[b].y - p[a].y) * (p[b].y - p[a].y) + (p[b].x - p[a].x) * (p[b].x - p[a].x));
}
int calc_distance(int n)
{
    int k = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = i + 1; j < n; j++)
        {
            double t = calct(i, j);
            if (t >= 10.0 && t <= 1000.0)
            {
                E[k].s = i;
                E[k].e = j;
                E[k++].dis = t;
            }
        }
    }
    return k;
}
bool cmp(edge a, edge b)
{
    return a.dis < b.dis;
}
int find(int x)
{
    while (x != father[x])
        x = father[x];
    return father[x];
}
bool merge(int a, int b)
{
    int ta = find(a);
    int tb = find(b);
    if (ta == tb)
        return false;
    if (num[ta] > num[tb])
    {
        father[tb] = ta;
        num[ta] += num[tb];
    }
    else
    {
        father[ta] = tb;
        num[tb] += num[ta];
    }
    return true;
}
bool kruskal(int n, int len)
{
    int k = 0;
    for (int i = 0; i < len; i++)
    {
        if (merge(E[i].s, E[i].e))
        {
            ++k;
            ans += E[i].dis;
        }
        if (k == n - 1)
            break;
    }
    if (k == n - 1)
        return true;
    return false;
}
int main()
{
    int t,n;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d", &n);
        init(n);
        ans = 0.0;
        for (int i = 0; i < n; i++)
            scanf("%d %d", &p[i].x, &p[i].y);
        int len = calc_distance(n);
        sort(E, E + len, cmp);
        if (kruskal(n, len))
        {
            printf("%.1f
", ans * 100.0);
        }
        else
            puts("oh!");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Howe-Young/p/4370151.html