标签:
Highways Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
Description
Input
Output
Sample Input
9 1 5 0 0 3 2 4 5 5 1 0 4 5 2 1 2 5 3 3 1 3 9 7 1 2
Sample Output
1 6 3 7 4 9 5 7 8 3
最小生成树,有的树之间有联系, 有的没有。求怎样连可以把所有点在一棵树上,而且权值和最小。只要权值最小就行。关键是怎样连最小,
已经确定有联系的树的权值要避免对接下来最小值的判断的影响,全置为-1,表示这两点边权值最小,看其他边权值的比较,谁最小连谁,最后根据边权值是否> 0判断是否新连接的
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define N 1100 #define INF 0xfffffff int n, m, vis[N]; double maps[N][N]; struct node { int x, y; }P[N]; // 存该点坐标 struct point { int v; double len; }Q[N]; // 存该点连到树上的长度len,和通过谁连到的树上v void prim() { vis[1] = 1; for(int i = 1; i <= n; i++) Q[i].len = maps[i][1], Q[i].v = 1; // 最开始都是通过1连到树上的,距离也是其与1的距离,已经连上的是-1,最小的 for(int i = 1; i < n; i++) { int index = 0; double Min = INF; for(int j = 1; j <= n; j++) { if(!vis[j] && Q[j].len < Min) Min = Q[j].len, index = j; } vis[index] = 1; for(int j = 1; j <= n; j++) { if(!vis[j] && Q[j].len > maps[j][index]) Q[j].len = maps[j][index], Q[j].v = index; // 求最小生成树,如果边权值改变,所连的树 v 也改变,本题也就是问你树跟哪棵树边权值连最小 } } } int main() { int a, b; while(cin >> n) { memset(vis, 0, sizeof(vis)); for(int i = 1; i <= n; i++) { cin >> P[i].x >> P[i].y; } for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { int nx = P[i].x-P[j].x, ny = P[i].y-P[j].y; double g = sqrt(nx*nx+ny*ny); maps[i][j] = maps[j][i] = g; // 求两棵树的距离 } } cin >> m; for(int j = 0; j < m; j++) { cin >> a >> b; maps[a][b] = maps[b][a] = -1; } prim(); for(int j = 2; j <= n; j++) { if(Q[j].len > 0) printf("%d %d\n", j, Q[j].v); // 如果边权值是-1,小于0,就是该点已经连到树上,就不用输出,反之就是要连接的树~和其边权值 } } return 0; }
专题链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82831#overview
标签:
原文地址:http://www.cnblogs.com/Tinamei/p/4684125.html