poj2075

最小生成树,我是用邻接表+map存储姓名做的,点开1000就够了。

View Code
#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <map>

using namespace std;



#define inf 0x3f3f3f3f

#define maxn 1005

#define maxl 25



struct Edge

{

    int v, next;

    double w;

}edge[maxn * maxn];



int vis[maxn];

double lowc[maxn];

double len;

int n, m;

int head[maxn];

int ncount;

map <string, int> name;



void addedge(int a, int b, double w)

{

    edge[ncount].v = b;

    edge[ncount].next = head[a];

    edge[ncount].w = w;

    head[a] = ncount++;

}



void input()

{

    scanf("%lf%d", &len, &n);

    for (int i = 0; i < n; i++)

    {

        char ch[maxl];

        scanf("%s", ch);

        string st(ch);

        name[ch] = i;

    }

    scanf("%d", &m);

    for (int i = 0; i < m; i++)

    {

        char ch1[maxl], ch2[maxl];

        double w;

        scanf("%s%s%lf", ch1, ch2, &w);

        string st1(ch1), st2(ch2);

        int a = name[st1];

        int b = name[st2];

        addedge(a, b, w);

        addedge(b, a, w);

    }

}



double prim()

{

    memset(vis, 0, sizeof(vis));

    for (int i = 0; i < n; i++)

        lowc[i] = inf;

    lowc[0] = 0;

    double ret = 0;

    lowc[n] = inf;

    while (true)

    {

        int u = n;

        for (int i = 0; i < n; i++)

            if (lowc[u] > lowc[i] && !vis[i])

                u = i;

        if  (u == n)

            break;

        vis[u] = true;

        ret += lowc[u];

        lowc[u] = 0;

        for (int i = head[u]; ~i; i = edge[i].next)

        {

            int v = edge[i].v;

            lowc[v] = min(lowc[v], edge[i].w);

        }

    }

    return ret;

}



int main()

{

    //freopen("t.txt", "r", stdin);

    memset(head, -1, sizeof(head));

    ncount = 0;

    input();

    double ans = prim();

    if (ans > len)

        printf("Not enough cable\n");

    else

        printf("Need %.1f miles of cable\n", ans);

    return 0;

}

你可能感兴趣的:(poj)