zoukankan      html  css  js  c++  java
  • HDU 1102 Constructing Roads (最小生成树)

    最小生成树模板(嗯……在kuangbin模板里面抄的……)

    最小生成树(prim)
    /** Prim求MST
      * 耗费矩阵cost[][],标号从0开始,0~n-1
      * 返回最小生成树的权值,返回-1表示原图不连通
      */
    const int INF = 0x3f3f3f3f;
    const int MAXN = 110;
    
    bool vis[MAXN];
    int lowc[MAXN];
    int map[MAXN][MAXN];
    
    int Prim(int cost[][MAXN], int n)
    {
        int ans = 0;
        memset(vis, false, sizeof(vis));
        vis[0] = true;
        for (int i = 1; i < n; ++i) lowc[i] = cost[0][i];
        for (int i = 1; i < n; ++i) {
            int minc = INF;
            int p = 1;
            for (int j = 0; j < n; ++j)
                if (!vis[j] && minc > lowc[j]) {
                    minc = lowc[j];
                    p = j;
                }
            if (minc == INF) return -1;
            ans += minc;
            vis[p] = true;
            for (int j = 0; j < n; ++j)
                if (!vis[j] && lowc[j] > cost[p][j])
                    lowc[j] = cost[p][j];
        }
        return ans;
    }
    

    感觉Prim和Dijkstra有点像。写起来挺简单的。

    我一开始的想法是把每个q中的a,b设为已访问节点,后来发现不对,例如ab连,dc连,但它们并不是全部相连的。

    好吧其实此题就是把已建好两点之间距离设为0.

    //Problem : 1102 ( Constructing Roads )     Judge Status : Accepted
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int N = 105;
    const int INF = 3000;
    
    int map[N][N];
    int vis[N];
    int dis[N];
    
    int Prim(int n)
    {
        int ans = 0;
        memset(vis, 0, sizeof(vis));
        for (int j = 1; j <= n; ++j) {
            dis[j] = map[1][j];
        }
        for (int k = 1; k <= n; ++k) {
            int minc = INF;
            int p = 1;
            for (int i = 1; i <= n; ++i) {
                if (!vis[i] && dis[i] < minc) {
                    minc = dis[i];
                    p = i;
                }
            }
            if (minc == INF) return -1;
            ans += minc;
            vis[p] = 1;
            for (int j = 1; j <= n; ++j) {
                if (map[p][j] < dis[j] && !vis[j])
                    dis[j] = map[p][j];
            }
        }
        return ans;
    }
    
    int main()
    {
        int n, q;
        while (cin >> n) {
            for (int i = 1; i <= n; ++i)
                for (int j = 1; j <= n; ++j)
                    cin >> map[i][j];
            cin >> q;
            int a, b;
            for (int i = 0; i < q; ++i) {
                cin >> a >> b;
                map[a][b] = map[b][a] = 0;
            }
            cout << Prim(n) << endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    基于MATLAB求解矩阵的正交补矩阵
    MySQL的安装与配置
    删除ubuntu后修复win7系统的引导
    VS2010中快捷添加命名空间
    java学习之函数
    java学习之break 和 continue
    For循环复杂练习
    For循环练习之99乘法表和转义字符
    java学习之语句结构
    java学习之运算符
  • 原文地址:https://www.cnblogs.com/wenruo/p/4573892.html
Copyright © 2011-2022 走看看