zoukankan      html  css  js  c++  java
  • HDU 4009 不定根最小树形图

    讲一下建图过程,首先建立一个超级源点S,对于这个源点,向每个HOUSE连一条有向边,权值为该HOUSE建立WELL的费用,即高度*X。

    然后每个可以连边的WELL之间,费用为曼哈顿距离*Y,然后考虑两边的高度,如果需要连接PUMB,则在该费用上+Z。

    这样建图之后,以S为根,跑一遍最小树形图算法即可。

    CODE:

    #include <set>
    #include <map>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <iomanip>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define Max 2505
    #define FI first
    #define SE second
    #define ll long long
    #define PI acos(-1.0)
    #define inf 0x3fffffff
    #define LL(x) ( x << 1 )
    #define bug puts("here")
    #define PII pair<int,int>
    #define RR(x) ( x << 1 | 1 )
    #define mp(a,b) make_pair(a,b)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )
    
    using namespace std;
    
    inline void RD(int &ret) {
        char c;
        int flag = 1 ;
        do {
            c = getchar();
            if(c == '-')flag = -1 ;
        } while(c < '0' || c > '9') ;
        ret = c - '0';
        while((c=getchar()) >= '0' && c <= '9')
            ret = ret * 10 + ( c - '0' );
        ret *= flag ;
    }
    
    inline void OT(int a) {
        if(a >= 10)OT(a / 10) ;
        putchar(a % 10 + '0') ;
    }
    
    /*********************************************/
    #define N 1005
    int n , X , Y , Z ;
    struct C{
        int x , y , z ;
    }city[N] ;
    int num = 0 ;
    int S ;
    void init(){
        num = S = 0 ;
    }
    struct kdq{
        int s ,e ,l ;
    }E[N * N] ;
    int get_Mandis(int i ,int j){
        return abs(city[i].x - city[j].x) + abs(city[i].y - city[j].y) + abs(city[i].z - city[j].z) ;
    }
    void add(int s ,int e ,int l){
        E[num].s = s ;
        E[num].e = e ;
        E[num].l = l ;
        num ++ ;
    }
    int pre[N] , vis[N] , id[N] , in[N] ;
    int Directed_MST(int root ,int NV ,int NE){
        int ret = 0 ;
        while(1){
            for (int i = 0 ; i < NV ; i ++ )in[i] = inf ;
            for (int i = 0 ; i < NE ; i ++ ){
                int s = E[i].s ;
                int e = E[i].e ;
                if(in[e] > E[i].l && s != e){
                    in[e] = E[i].l ;
                    pre[e] = s ;
                }
            }
            for (int i = 0 ; i < NV ; i ++ ){
                if(i == root)continue ;
                if(in[i] == inf)return -1 ;
            }
            int cntnode = 0 ;
            mem(vis , -1) ;
            mem(id , -1) ;
            in[root] = 0 ;
            for (int i = 0 ; i < NV ; i ++ ){
                ret += in[i] ;
                int v = i ;
                while(vis[v] != i && id[v] == -1 && v != root){
                    vis[v] = i ;
                    v = pre[v] ;
                }
                if(v != root && id[v] == -1){
                    for (int u = pre[v] ; u != v ; u = pre[u]){
                        id[u] = cntnode ;
                    }
                    id[v] = cntnode ++ ;
                }
            }
            if(cntnode == 0)break ;
            for (int i = 0 ; i < NV ; i ++ )if(id[i] == -1)id[i] = cntnode ++ ;
            for (int i = 0 ; i < NE ; i ++ ){
                int s = E[i].s ;
                int e = E[i].e ;
                E[i].s = id[s] ;
                E[i].e = id[e] ;
                if(id[s] != id[e])E[i].l -= in[e] ;
            }
            NV = cntnode ;
            root = id[root] ;
        }
        return ret ;
    }
    int main() {
        int a , k ;
        while(scanf("%d%d%d%d",&n,&X,&Y,&Z) , ( n + X + Y + Z)){
            init() ;
            for (int i = 1 ; i <= n ;i ++ ){
                RD(city[i].x) ;RD(city[i].y) ;RD(city[i].z) ;
            }
            for (int i = 1 ; i <= n ; i ++ ){
                RD(k) ;
                while(k -- ){
                    RD(a) ;
                    if(i == a)continue ;//自环
                    int dis = get_Mandis(i , a) * Y ;
                    if(city[i].z < city[a].z)dis += Z ;
                    add(i , a , dis) ;
                }
            }
            for (int i = 1 ; i <= n ; i ++ ){
                add(S , i , city[i].z * X) ;
            }
            int ans = Directed_MST(0 , n + 1 , num) ;
            if(ans == -1)puts("poor XiaoA") ;
            else OT(ans) ;
            puts("") ;
        }
        return 0 ;
    }
    


  • 相关阅读:
    oracle 数据库服务名怎么查
    vmware vsphere 6.5
    vSphere虚拟化之ESXi的安装及部署
    ArcMap中无法添加ArcGIS Online底图的诊断方法
    ArcGIS中字段计算器(高级计算VBScript、Python)
    Bad habits : Putting NOLOCK everywhere
    Understanding the Impact of NOLOCK and WITH NOLOCK Table Hints in SQL Server
    with(nolock) or (nolock)
    What is “with (nolock)” in SQL Server?
    Changing SQL Server Collation After Installation
  • 原文地址:https://www.cnblogs.com/james1207/p/3268558.html
Copyright © 2011-2022 走看看