zoukankan      html  css  js  c++  java
  • HDOJ 4009Transfer water最小树形图解题报告

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4009

    这道题是说一个村庄里的人家住在不同的位置,而且有不同的高度,每户人家可以自己修建水井,也可以选择从别的人家修建引水渠,并且回因为位置的高低产生不同的费用,首先,每户人家都可以选择自己修建水井,所以不存在无解的情况,然后,建立一个虚拟根,从根出发到第i个节点有权值为这户人家自己修建水井的费用,如果i能从j引水,从j到i建立一条权值为修建引水渠费用的边,最后要找的就是这个有向图的最小树形图。关于最小树形图百度百科有详细的描述和算法介绍,可以参照代码进行比对。

    View Code
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #define N 1005
      5 #define inf 0x7fffffff
      6 using namespace std;
      7 struct point
      8 {
      9     int x,y,z;
     10 };
     11 int Abs(int a)
     12 {
     13     return a<0?-a:a;
     14 }
     15 point p[N];
     16 int dis(point p1,point p2)
     17 {
     18     return Abs(p1.x-p2.x)+Abs(p1.y-p2.y)+Abs(p1.z-p2.z);
     19 }
     20 int cnt;
     21 struct node
     22 {
     23     int u,v,w;
     24 };
     25 node e[N*N];
     26 int n,id[N],vis[N],pre[N],in[N];
     27 void init()
     28 {
     29     cnt=0;
     30 }
     31 void add(int u,int v,int w)
     32 {
     33     e[cnt].u=u,e[cnt].v=v,e[cnt++].w=w;
     34 }
     35 int directedMST(int root)
     36 {
     37     int res=0,cntnode,nv=n;
     38     int i,j,k,u,v;
     39     while(1)
     40     {
     41         for(i=0;i<nv;i++)
     42         {
     43             in[i]=inf;
     44         }
     45         for(i=0;i<cnt;i++)
     46         {
     47             u=e[i].u;
     48             v=e[i].v;
     49             if(in[v]>e[i].w&&u!=v)
     50             {
     51                 pre[v]=u;
     52                 in[v]=e[i].w;
     53             }
     54         }
     55         for(i=0;i<nv;i++)
     56         {
     57             if(i==root)
     58             continue;
     59             if(in[i]==inf)
     60             return -1;
     61         }
     62         in[root]=0;
     63         memset(id,-1,sizeof(id));
     64         memset(vis,-1,sizeof(vis));
     65         cntnode=0;
     66         for(i=0;i<nv;i++)
     67         {
     68             res+=in[i];
     69             v=i;
     70             while(vis[v]!=i&&id[v]==-1&&v!=root)//找自环
     71             {
     72                 vis[v]=i;
     73                 v=pre[v];
     74             }
     75             if(v!=root&&id[v]==-1)//缩点
     76             {
     77                 for(u=pre[v];u!=v;u=pre[u])
     78                 id[u]=cntnode;
     79                 id[v]=cntnode++;
     80             }
     81         }
     82         if(cntnode==0)
     83         break;
     84         for(i=0;i<nv;i++)
     85         if(id[i]==-1)
     86         id[i]=cntnode++;
     87         for(i=0;i<cnt;i++)
     88         {
     89             v=e[i].v;
     90             e[i].u=id[e[i].u];
     91             e[i].v=id[e[i].v];
     92             if(e[i].u!=e[i].v)
     93             e[i].w-=in[v];
     94         }
     95         nv=cntnode;
     96         root=id[root];
     97     }
     98     return res;
     99 }
    100 int main()
    101 {
    102     int X,Y,Z,u,v,i,j,k,cost;
    103     while(scanf("%d%d%d%d",&n,&X,&Y,&Z)&&(n||X||Y||Z))
    104     {
    105         init();
    106         n++;
    107         for(i=1;i<n;i++)
    108         {
    109             scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z);
    110             add(0,i,p[i].z*X);
    111         }
    112         for(i=1;i<n;i++)
    113         {
    114             scanf("%d",&k);
    115             while(k--)
    116             {
    117                 scanf("%d",&u);
    118                 if(u==i)
    119                 continue;
    120                 cost=dis(p[u],p[i])*Y;
    121                 if(p[u].z>p[i].z)
    122                 cost+=Z;
    123                 add(i,u,cost);
    124             }
    125         }
    126         printf("%d\n",directedMST(0));
    127     }
    128     return 0;
    129 }
  • 相关阅读:
    第三章 Jenkins参数及web项目
    第二章 Jenkins的详细介绍
    第一章 Git+Gitlab介绍和安装
    第二章 Centos7下Airflow2.1.0安装
    第一章 Airflow基本原理
    第五章 Pinpoint-Apm常见报错
    第四章 Docker方式安装 Pinpoint
    数论练习
    CF练习
    矩阵乘法
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2673496.html
Copyright © 2011-2022 走看看