poj1258 生成樹入門

題意:n個點,n*n的矩陣表示邊,求最小生成樹

(1)prim O(n^2)

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 110;
const int INF = 0x3f3f3f3f;
int g[N][N];
int dis[N];
bool vis[N];
int n;

int prim()
{
    int ret = 0;
    for(int i = 1; i <= n; ++i) dis[i] = INF;
    dis[1] = 0;
    memset(vis, 0, sizeof(vis));
    for(int i = 1; i <= n; ++i)
    {
        int mm = INF, p = -1;
        for(int j = 1; j <= n; ++j)
            if(!vis[j] && dis[j]<mm)
                mm = dis[p=j];
        if(p==-1) break;
        vis[p] = 1;
        ret += dis[p];
        for(int j = 1; j <= n; ++j)
            if(!vis[j])
                dis[j] = min(dis[j], g[p][j]);
    }
    return ret;
}

int main()
{
    while(~scanf("%d", &n))
    {
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j)
                scanf("%d", &g[i][j]);
        printf("%d\n", prim());
    }
    return 0;
}

(2)kruskal O(mlogn)

#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 110;
const int M = 10010;
struct node
{
    int u, v, w;
    node(){}
    node(int _u, int _v, int _w)
    {
        u = _u; v = _v; w = _w;
    }
    bool operator <(const node &p)const
    {
        return w<p.w;
    }
}edge[M];
int tot;
int fa[N];
int n;

int findf(int x)
{
    return x==fa[x]?x:fa[x]=findf(fa[x]);
}

bool merge_(int x, int y)
{
    int f1 = findf(x);
    int f2 = findf(y);
    if(f1==f2) return 0;
    fa[f1] = f2;
    return 1;
}

int kruskal()
{
    sort(edge+1, edge+tot+1);
    int ret = 0;
    int cnt = 0;
    for(int i = 1; i <= tot; ++i)
    {
        if(merge_(edge[i].u, edge[i].v))
        {
            ++cnt;
            ret += edge[i].w;
        }
        if(cnt==n-1) break;
    }
    return ret;
}

int main()
{
    while(~scanf("%d", &n))
    {
        for(int i = 1; i <= n; ++i) fa[i] = i;
        tot = 0;
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j)
            {
                int x;
                scanf("%d", &x);
                if(i>=j) continue;
                edge[++tot] = node(i, j, x);
            }
        printf("%d\n", kruskal());
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章