标签:
畅通工程再续 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description
Input
Output
Sample Input
Sample Output
#include<iostream> #include<cstring> #include<cmath> #include<cstdio> using namespace std; #define N 110 #define INF 0xfffffff struct node { int x, y; } P[N]; int vis[N]; double maps[N][N], dist[N]; void init() { for(int i = 0; i < N; i++) { vis[i] = 0; for(int j = 0; j < N; j++) { maps[i][j] = maps[j][i] = INF; } } } double prim(int n) { vis[0] = 1; dist[0] = 0; int cou = 1; double ans = 0; for(int i = 0; i < n; i++) dist[i] = maps[0][i]; for(int i = 0; i < n; i++) { int index, f; double Min = INF; index = f = 0; for(int j = 0; j < n; j++) { if(!vis[j] && dist[j] < Min) Min = dist[j], index = j, f = 1; // 如果边权值满足题意,并且该点没有连接的话,f置为1,就把该值用上联通该点 } if(f) { cou++; // cou计算已经被连接的点数,加一次边权值,联通点数加一 vis[index] = 1; ans += Min; } for(int j = 0; j < n; j++) { if(!vis[j] && dist[j] > maps[j][index]) dist[j] = maps[j][index]; // 最短路 } } if(cou != n) return -1; return ans; } int main() { int t, c; cin >> t; while(t--) { cin >> c; init(); for(int i = 0; i < c; i++) cin >> P[i].x >> P[i].y; for(int i = 0; i < c; i++) { for(int j = 0; j < c; j++) { int xx = P[i].x-P[j].x, yy = P[i].y-P[j].y; double q = sqrt(xx*xx+yy*yy); if(q >= 10 && q <= 1000) maps[i][j] = maps[j][i] = q; // 边权值即两点距离满足题意,就可以用,不然边权值就是INF,已初始化 } } double ans = prim(c); if(ans == -1) cout << "oh!" << endl; else printf("%.1f\n", ans*100); } return 0; }
算法:Kruskal 和Prim 区别
* Kruskal:将所有边从小到大加入,在此过程中
判断是否构成回路
– 使用数据结构:并查集
– 时间复杂度:O(ElogE)
– 适用于稀疏图
* Prim:从任一节点出发,不断扩展
– 使用数据结构:堆
– 时间复杂度:O(ElogV) 或O(VlogV+E)(斐波那契堆)
– 适用于密集图
2
– 若不用堆则时间复杂度为O(V )
标签:
原文地址:http://www.cnblogs.com/Tinamei/p/4681089.html