标签:
http://poj.org/problem?id=1751
题意:有n个点,已知各点坐标,距离为权值,求最小生成树的边
但是这个最小生成树的m条边是已经确定的了,所以可以让已知边的权值为0;
在Prim算法中改一下就行
#include<stdio.h> #include<string.h> #include<map> #include<iostream> #include<algorithm> #include<math.h> #define N 1100 #define INF 0xfffffff using namespace std; int vis[N], n, pre[N];//pre[i]记录的是i的父节点; double maps[N][N],dist[N]; void Prim(int start) { vis[start] = 1; for(int i=1; i<=n; i++) { dist[i] = maps[start][i]; pre[i] = start; } for(int i=1; i<=n; i++) { double Min = INF; int index = -1; for(int j = 1; j <= n; j++) { if(vis[j]==0 && Min>dist[j]) { Min = dist[j]; index = j; } } if(index == -1) break; if(Min != 0) printf("%d %d\n", pre[index],index); vis[index] = 1; for(int j=1; j<=n; j++) { if(vis[j]==0 && dist[j] > maps[index][j]) dist[j] = maps[index][j], pre[j] = index; } } } struct node { int x, y; }a[N]; void Init() { for(int i=0;i<=n;i++) { pre[i] = i; vis[i] = 0; dist[i] = INF; for(int j=0; j<=n; j++) maps[i][j] = INF; maps[i][i] = 0; } } int main() { int i, j, x, y, m; double d; while(scanf("%d", &n)!=EOF) { Init(); memset(a,0,sizeof(a)); for(i=1;i<=n;i++) scanf("%d%d", &a[i].x, &a[i].y); for(i=1; i<=n; i++) { for(j=i+1; j<=n; j++) { d = sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)); maps[i][j] = maps[j][i] = d; } } scanf("%d", &m); for(i=0; i<m; i++) { scanf("%d%d", &x,&y); maps[x][y] = maps[y][x] = 0; //把已知边的权值置为0; } Prim(1); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zhengguiping--9876/p/4682089.html