已经存在一些边,求其最小生成树。
可以把存在的边权赋值为0,那么做最小生成树的时候一定会把存在的边给选进去,然后最裸的最小生成树即可。
hdu1879也可以这样。
AC代码:
#include <cstdio> #include <string.h> #include <cmath> #define max(a,b) ((a) > (b)) ? (a) : (b) const int MAX_POINT = 770; const int INF = 10000000; const double eps = 1e-6; struct Point { int x; int y; }; struct Point point[MAX_POINT]; double maps[MAX_POINT][MAX_POINT]; double lowest[MAX_POINT], ans; int vis[MAX_POINT]; int point_number, exist_number; double getDistance(int i, int j) { int x = point[i].x - point[j].x; int y = point[i].y - point[j].y; return sqrt(x * x + y * y + eps); } void prim() { memset(vis, 0, sizeof(vis)); memset(lowest, 0, sizeof(lowest)); for (int i = 1; i <= point_number; i++) { lowest[i] = maps[1][i]; } vis[1] = 1; ans = 0; for (int i = 1; i < point_number; i++) { double min_ans = INF; int cnt_point; for (int j = 1; j <= point_number; j++) { if (!vis[j] && lowest[j] < min_ans) { cnt_point = j; min_ans = lowest[j]; } } ans += min_ans; vis[cnt_point] = 1; for (int j = 1; j <= point_number; j++) { if (!vis[j] && lowest[j] > maps[cnt_point][j]) { lowest[j] = maps[cnt_point][j]; } } } } int main() { while (scanf("%d", &point_number) != EOF) { memset(maps, 0, sizeof(maps)); for (int i = 1; i <= point_number; i++) { scanf("%d%d", &point[i].x, &point[i].y); } for (int i = 1; i <= point_number; i++) { maps[i][i] = 0; for (int j = i + 1; j <= point_number; j++) { maps[i][j] = maps[j][i] = getDistance(i, j); } } scanf("%d", &exist_number); for (int i = 1; i <= exist_number; i++) { int start, end; scanf("%d%d", &start, &end); maps[start][end] = maps[end][start] = 0; } prim(); printf("%.2lf\n", ans); } return 0; }