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 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    LOJ 6089 小Y的背包计数问题 —— 前缀和优化DP
    洛谷 P1969 积木大赛 —— 水题
    洛谷 P1965 转圈游戏 —— 快速幂
    洛谷 P1970 花匠 —— DP
    洛谷 P1966 火柴排队 —— 思路
    51Nod 1450 闯关游戏 —— 期望DP
    洛谷 P2312 & bzoj 3751 解方程 —— 取模
    洛谷 P1351 联合权值 —— 树形DP
    NOIP2007 树网的核
    平面最近点对(加强版)
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4547542.html
Copyright © 2011-2022 走看看