标签:
题目链接:
http://poj.org/problem?id=1751
题目大意:
给出n个点,每个点用二维坐标表示,不会用任意两个点在同一位置,在这n个点之间已经有m条道路了,问在花费最少的情况下修建那几条路能把所有的点连在一起?
解题思路:
对任意一个点向其他的点建边,因为建图的时候,边比较密集,所以最好用prim算法求最短路,ps:我刚开始是多实例,一直tle,最后搜了一下题解,发现别人也是多实例,无奈最后改成单实例试试,竟然对了,为什么???难道大神怎么写都对,大神就是任性??有同学发现为什么请告诉我,跪谢ing
1 #include <cmath> 2 #include <string> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 8 using namespace std; 9 const int maxn = 760; 10 const int INF = 0x3f3f3f3f; 11 const double Exp = 1e-10; 12 int cost[maxn][maxn], lowc[maxn]; 13 int vis[maxn], pre[maxn]; 14 //pre[i]记录i的前驱 15 struct point 16 { 17 int x, y; 18 }; 19 20 int length (point a, point b) 21 { 22 return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y); 23 } 24 void prim (int n) 25 { 26 int i, j; 27 memset (vis, 0, sizeof(vis)); 28 vis[1] = 1; 29 for (i=1; i<=n; i++) 30 { 31 pre[i] = 1; 32 lowc[i] = cost[1][i]; 33 } 34 35 for (i=1; i<n; i++) 36 { 37 int p; 38 int mini = INF; 39 for (j=1; j<=n; j++) 40 if (!vis[j] && mini > lowc[j]) 41 { 42 p = j; 43 mini = lowc[j]; 44 } 45 if (cost[p][pre[p]] != 0)//需要建路 46 printf ("%d %d\n", pre[p], p); 47 vis[p] = 1; 48 for (j=1; j<=n; j++) 49 { 50 if (!vis[j] && lowc[j] > cost[p][j]) 51 { 52 lowc[j] = cost[p][j]; 53 pre[j] = p; 54 } 55 } 56 } 57 } 58 59 int main () 60 { 61 int n; 62 point p[maxn]; 63 scanf ("%d", &n); 64 for (int i=1; i<=n; i++) 65 { 66 scanf ("%d %d", &p[i].x, &p[i].y); 67 for (int j=1; j<i; j++) 68 cost[i][j] = cost[j][i] = length(p[i], p[j]); 69 cost[i][i] = 0; 70 } 71 72 int m; 73 scanf ("%d", &m); 74 while (m --) 75 {//把已经建过路的点聚集在一起 76 int x, y; 77 scanf ("%d %d", &x, &y); 78 cost[x][y] = cost[y][x] = 0; 79 } 80 prim(n); 81 return 0; 82 }
标签:
原文地址:http://www.cnblogs.com/alihenaixiao/p/4547542.html