andre_joy

导航

hdu 1233

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1233

题意:中文。。

mark:这就是传说中的最小生成树。。。第一次做最小生成树,看别人题解说是很裸的,思路也很简单。

    第一次随便取一个点,比如a1,则集合变成{a1}, {a2, a3, ...},然后从右边的集合找到一个距离左边集合最近的点加入左边,以此重复n-1次。

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>

using namespace std;

typedef long long LL;

int n;
int Min[110];
int vst[110];
int dis[110][110];

void solve()
{
    int i,j;
    memset(vst, 0, sizeof(vst));
    memset(Min, 0x3f, sizeof(Min));
    int x = 1;
    vst[1] = 1;
    int sum = 0;
    for(i = 2; i <= n; i++)
        Min[i] = min(Min[i], dis[1][i]);
    for(i = 1; i < n; i++)
    {
        int tem = 10000000;
        for(j = 1; j <= n; j++)
            if(!vst[j] && tem > Min[j])
            {
                tem = Min[j];
                x = j;
            }
        sum += tem;
        vst[x] = 1;
        for(j = 1; j <= n; j++)
            if(!vst[j] && dis[j][x] < Min[j])
                Min[j] = dis[j][x];
    }
    cout << sum << endl;
}

int main(int argc, char **argv)
{
    int i,j,k,p,q;
    while(scanf("%d", &n), n)
    {
        memset(dis, 0, sizeof(dis));
        for(i = 0; i < n*(n-1)/2; i++)
        {
            scanf("%d%d%d", &j, &k, &p);
            dis[j][k] = dis[k][j] = p;
        }
        solve();
    }
    return 0;
}

 

posted on 2013-05-31 22:37  andre_joy  阅读(323)  评论(0编辑  收藏  举报