zoukankan      html  css  js  c++  java
  • poj 1751 Highways (最小生成树)

    题目链接:

      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
    ", 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 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    自定义打包工具对应的解析代码
    自定义的打包工具源码
    一种C语言实现面向对象特性的继承,多态
    buffers和cached的区别
    初识rt-thread杂记
    一种多叉树的实现,提供树形结构打印,树转表输出等功能
    关于rtsp的时间戳问题
    一种基于状态机(表)的小组件
    一种基于消息发布-订阅的观察者模式实现
    命令解析类代码重构
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4547542.html
Copyright © 2011-2022 走看看