洛谷1265 公路修建【最小生成树】
作者:互联网
题目:https://www.luogu.org/problemnew/show/P1265
题意:有n个城市的坐标,每个城市申请和自己最近的城市建路,这之后他们就被视为一个城市。
继续下去直到所有城市都是一个城市。问最少建多少路。题目里说如果形成了环的话,就要去掉路最短的那个。
但是城市一个个请求过来,建完就变成一个城市了之后,怎么会形成环啊【反正好像这句话根本不用管】
思路:这道题的题意好奇怪。刚开始看半天搞不懂还以为要求最大生成树嘞。其实就是一个最小生成树而已。
因为点比较多,所以图就不存了,直接prim的时候用dist函数算。
注意dist函数里面,x和y原来是整型先给他们转成double。有的题目里面没关系,这道题目就WA了。还是都先注意以下吧。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<map> 4 #include<set> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<cmath> 9 #include<stack> 10 #include<queue> 11 #include<iostream> 12 13 #define inf 0x3f3f3f3f 14 using namespace std; 15 typedef long long LL; 16 typedef pair<int, int> pr; 17 18 const int maxn = 5005; 19 int n; 20 struct node{ 21 int x, y; 22 }city[maxn]; 23 //double g[maxn][maxn]; 24 double d[maxn]; 25 bool vis[maxn]; 26 double ans = 0; 27 28 double dist(int i, int j) 29 { 30 return sqrt((double)(city[i].x - city[j].x) * (city[i].x - city[j].x) + (double)(city[i].y - city[j].y) * (city[i].y - city[j].y)); 31 } 32 33 void prim(int st) 34 { 35 vis[st] = true; 36 d[st] = 0; 37 for(int i = 1; i <= n; i++){ 38 d[i] = dist(st, i); 39 } 40 for(int t = 1; t < n; t++){ 41 double min = inf; 42 int minid; 43 for(int i = 1; i <= n; i++){ 44 if(!vis[i] && d[i] < min){ 45 min = d[i]; 46 minid = i; 47 } 48 } 49 vis[minid] = true; 50 ans += min; 51 for(int i = 1; i <= n; i++){ 52 if(d[i] > dist(minid, i)){ 53 d[i] = dist(minid, i); 54 } 55 } 56 } 57 } 58 59 int main() 60 { 61 scanf("%d", &n); 62 memset(d, 0x3f, sizeof(d)); 63 for(int i = 1; i <= n; i++){ 64 //par[i] = i; 65 scanf("%d%d", &city[i].x, &city[i].y); 66 } 67 // for(int i = 1; i <= n; i++){ 68 // for(int j = i + 1; j <= n; j++){ 69 // g[i][j] = g[j][i] = dist(i, j); 70 // //printf("%lf\n", g[i][j]); 71 // } 72 // } 73 74 prim(1); 75 printf("%.2lf\n", ans); 76 return 0; 77 }
标签:city,洛谷,int,double,最小,1265,maxn,dist,include 来源: https://www.cnblogs.com/wyboooo/p/11118509.html