题目链接:
https://vjudge.net/problem/POJ-2349
题目大意:
要在n个节点之间建立通信网络,其中m个节点可以用卫星直接连接,剩下的节点都要用线路连接,求剩下这些线路中最大的长度需要多长
思路:
还是MST的裸题,由于有m个节点可以用卫星连接,所以求出MST后,最长的m-1条边都可以用卫星连接,只需要求出第m长的边即可,直接用prim算法,保存mst每条边的长度,排序后直接输出第m长的边。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #include<stack> 8 #include<map> 9 #include<set> 10 #include<sstream> 11 using namespace std; 12 typedef long long ll; 13 typedef pair<int, int> Pair; 14 const int maxn = 1e3 + 10; 15 const int INF = 1 << 30; 16 int dir[4][2] = {1,0,0,1,-1,0,0,-1}; 17 int T, n, m; 18 double Map[maxn][maxn];//存图 19 double lowcost[maxn], ans[maxn]; 20 int mst[maxn], tot; 21 Pair a[maxn]; 22 void prim(int u)//最小生成树起点 23 { 24 for(int i = 1; i <= n; i++)//初始化两个数组 25 { 26 lowcost[i] = Map[u][i]; 27 mst[i] = u; 28 } 29 mst[u] = -1;//设置成-1表示已经加入mst 30 for(int i = 1; i <= n; i++) 31 { 32 double minn = INF; 33 int v = -1; 34 //在lowcost数组中寻找未加入mst的最小值 35 for(int j = 1; j <= n; j++) 36 { 37 if(mst[j] != -1 && lowcost[j] < minn) 38 { 39 v = j; 40 minn = lowcost[j]; 41 } 42 } 43 if(v != -1)//v=-1表示未找到最小的边, 44 {//v表示当前距离mst最短的点 45 //printf("%d %d %d\n", mst[v], v, lowcost[v]);//输出路径 46 ans[tot++] = lowcost[v]; 47 mst[v] = -1; 48 for(int j = 1; j <= n; j++)//更新最短边 49 { 50 if(mst[j] != -1 && lowcost[j] > Map[v][j]) 51 { 52 lowcost[j] = Map[v][j]; 53 mst[j] = v; 54 } 55 } 56 } 57 } 58 //printf("weight of mst is %d\n", sum_mst); 59 sort(ans, ans + tot); 60 printf("%.2f\n", ans[n - m - 1]);//输出第m长的边 61 } 62 int main() 63 { 64 cin >> T; 65 while(T--) 66 { 67 cin >> m >> n; 68 for(int i = 1; i <= n; i++)cin >> a[i].first >> a[i].second; 69 for(int i = 1; i <= n; i++) 70 { 71 for(int j = 1; j <= n; j++) 72 Map[i][j] = Map[j][i] = sqrt((a[i].first - a[j].first) * (a[i].first - a[j].first) + (a[i].second - a[j].second) * (a[i].second - a[j].second)); 73 } 74 tot = 0; 75 prim(1); 76 } 77 return 0; 78 }