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; }