您的位置:首页 > 其它

poj 1751 Highways (最小生成树)

2015-06-02 20:14 281 查看
题目链接:

  http://poj.org/problem?id=1751

题目大意:

  给出n个点,每个点用二维坐标表示,不会用任意两个点在同一位置,在这n个点之间已经有m条道路了,问在花费最少的情况下修建那几条路能把所有的点连在一起?

解题思路:

  对任意一个点向其他的点建边,因为建图的时候,边比较密集,所以最好用prim算法求最短路,ps:我刚开始是多实例,一直tle,最后搜了一下题解,发现别人也是多实例,无奈最后改成单实例试试,竟然对了,为什么???难道大神怎么写都对,大神就是任性??有同学发现为什么请告诉我,跪谢ing

#include <cmath>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
const int maxn = 760;
const int INF = 0x3f3f3f3f;
const double Exp = 1e-10;
int cost[maxn][maxn], lowc[maxn];
int vis[maxn], pre[maxn];
//pre[i]记录i的前驱
struct point
{
int x, y;
};

int length (point a, point b)
{
return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
}
void prim (int n)
{
int i, j;
memset (vis, 0, sizeof(vis));
vis[1] = 1;
for (i=1; i<=n; i++)
{
pre[i] = 1;
lowc[i] = cost[1][i];
}

for (i=1; i<n; i++)
{
int p;
int mini = INF;
for (j=1; j<=n; j++)
if (!vis[j] && mini > lowc[j])
{
p = j;
mini = lowc[j];
}
if (cost[p][pre[p]] != 0)//需要建路
printf ("%d %d\n", pre[p], p);
vis[p] = 1;
for (j=1; j<=n; j++)
{
if (!vis[j] && lowc[j] > cost[p][j])
{
lowc[j] = cost[p][j];
pre[j] = p;
}
}
}
}

int main ()
{
int n;
point p[maxn];
scanf ("%d", &n);
for (int i=1; i<=n; i++)
{
scanf ("%d %d", &p[i].x, &p[i].y);
for (int j=1; j<i; j++)
cost[i][j] = cost[j][i] = length(p[i], p[j]);
cost[i][i] = 0;
}

int m;
scanf ("%d", &m);
while (m --)
{//把已经建过路的点聚集在一起
int x, y;
scanf ("%d %d", &x, &y);
cost[x][y] = cost[y][x] = 0;
}
prim(n);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: