zoukankan      html  css  js  c++  java
  • P1364 医院设置

    floyd

    用floyd求出任意一个两个点之间的最短距离,然后算一下以所有节点为根的情况下的距离之和最小值。
    复杂度:(O(n^3))

    #include<iostream>
    #include<cstring>
    
    using namespace std;
    
    const int N = 110, INF = 0x3f3f3f3f;
    
    int n;
    int g[N][N];
    int w[N];
    
    int main(){
        memset(g, 0x3f, sizeof g);
        
        cin >> n;
        
        for(int i = 1; i <= n; i ++){
            int a, b;
            cin >> w[i] >> a >> b;
            g[i][a] = g[i][b] = g[a][i] = g[b][i] = 1;
        }
        
        for(int i = 1; i <= n; i ++) g[i][i] = 0;
        
        for(int k = 1; k <= n; k ++)
            for(int i = 1; i <= n; i ++)
                for(int j = 1; j <= n; j ++)
                    g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
                    
        int res = INF;
        
        for(int i = 1; i <= n; i ++){
            int ans = 0;
            for(int j = 1; j <= n; j ++)
                if(i != j) ans += g[i][j] * w[j];
            
            res = min(res, ans);
        }
        
        cout << res;
                    
        return 0;
    }
    

    树的重心

    需要预处理出:

    1. 以一个结点为整棵树的根u(这个可以任选,这里选1,这个和后面的递推起点有关)的情况下,以每一个结点v为根的子树包括的所有人口s[v]
    2. 将医院建在1号点时的总距离f(1)

    递推方法:(f[v] = f[u] - s[v] + s[1] - s[v];),f[k]表示把医院建在k的总距离,s[k]表示包括k在内的以k为根的子树。
    解释:
    v为u的出边所到达的点,现在已知将医院建在u时的总距离f[u], 既然v为u的出边,那么以v为根的子树(包括v)本来是走到u的而现在只需要到v,那么就先需要将f[u]减去s[v], 而除去v的子树的所有节点(包括v)原本是要走到u的,而现在需要走到v,那么f[u]还需要加上s[1] (总人口) - s[v]

    复杂度:(O(n))

    #include<iostream>
    #include<cstring>
    #include<queue>
    
    using namespace std;
    
    const int N = 110, INF = 0x3f3f3f3f;
    
    struct Node{
        int l, r;
        int w;
    }tr[N];
    
    int n;
    int s[N];
    int f[N];
    int level[N];
    
    int dfs_1(int u){
        if(u == 0) return 0;
        s[u] += dfs_1(tr[u].l) + dfs_1(tr[u].r) + tr[u].w;
        return s[u];
    }
    
    
    void dfs_2(int u){
        int l = tr[u].l, r = tr[u].r;
        if(l){
            f[l] = f[u] - s[l] + s[1] - s[l];
            dfs_2(l);
        }
        
        if(r){
            f[r] = f[u] - s[r] + s[1] - s[r];
            dfs_2(r);
        }
    }
    
    
    int main(){
        cin >> n;
        
        for(int i = 1; i <= n; i ++){
            int l, r, w;
            cin >> w >> l >> r;
            
            tr[i] = {l, r, w};
        }
        
        dfs_1(1);
        
        memset(f, 0x3f, sizeof f);
        
        queue<int> q;
        
        q.push(1);
        level[1] = 0;
        f[1] = 0;
        
        while(q.size()){
            int h = q.front();
            q.pop();
            
            int l = tr[h].l, r = tr[h].r;
            level[l] = level[r] = ++ level[h];
            if(l) f[1] += tr[l].w * level[l], q.push(l);
            if(r) f[1] += tr[r].w * level[r], q.push(r);
        }
        
        dfs_2(1);
        
        int res = INF;
        
        for(int i = 1; i <= n; i ++) res = min(res, f[i]);
        
        cout << res;
        
        return 0;
    }
    
  • 相关阅读:
    Django 自带密码加密,自定密码加密方式 及自定义验证方式
    详细解读Jquery各Ajax函数:$.get(),$.post(),$.ajax(),$.getJSON()
    Django中请求的生命周期
    Django---ORM操作大全
    Django----中间件详解
    Delphi 使用Query组件的SQL查询
    Delphi 使用Tabel组件的记录查找
    Delphi 字段的操作
    Delphi 使用数据库浏览器
    Delphi 建立ODBC数据源
  • 原文地址:https://www.cnblogs.com/tomori/p/13862891.html
Copyright © 2011-2022 走看看