zoukankan      html  css  js  c++  java
  • HDU 4009 Transfer water

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

    题意:给出一个村庄(x,y,z)。每个村庄可以挖井或者修建水渠从其他村庄得到水。挖井有一个代价,修水渠有一个代价。另外A村庄只能向其指定的一些村庄供水。使得所有村庄有水求最小代价。

    思路,建立源节点0,向每个点连边视为挖井,如果从其他村庄得到水就相当于从那个点引一条有向边过来。

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 const int inf=1000000000;
     7 int tot,In[1000005],vis[1000005],pre[1000005],id[1000005];
     8 int X,Y,Z,n;
     9 struct Point{
    10     int x,y,z;
    11 }p[1000005];
    12 struct edge{
    13     int u,v,w;
    14 }e[1300005];
    15 void insert(int x,int y,int z){
    16     tot++;
    17     e[tot].u=x;
    18     e[tot].v=y;
    19     e[tot].w=z;
    20 }
    21 int dis(Point p1,Point p2){
    22     int ans=std::abs(p1.x-p2.x)+std::abs(p1.y-p2.y)+std::abs(p1.z-p2.z);
    23     ans*=Y;
    24     if (p1.z<p2.z) ans+=Z;
    25     return ans;
    26 }
    27 int directedMST(int rt){
    28     int res=0;
    29     while (1){
    30         for (int i=0;i<n;i++) In[i]=inf;
    31         for (int i=1;i<=tot;i++){
    32             int u=e[i].u,v=e[i].v;
    33             if (u!=v&&In[v]>e[i].w) In[v]=e[i].w,pre[v]=u;
    34         }
    35         for (int i=0;i<n;i++){
    36             if (i==rt) continue;
    37             if (In[i]==inf) return -1;
    38         }
    39         int cnt=0;
    40         for (int i=0;i<n;i++) vis[i]=id[i]=-1;
    41         In[rt]=0;
    42         for (int i=0;i<n;i++){
    43             res+=In[i];
    44             int v=i;
    45             while (vis[v]!=i&&id[v]==-1&&v!=rt){
    46                 vis[v]=i;
    47                 v=pre[v];
    48             }
    49             if (v!=rt&&id[v]!=-1){
    50                 for (int j=pre[v];j!=v;j=pre[j]){
    51                     id[j]=cnt;
    52                 }
    53                 id[v]=cnt++;
    54             }
    55         }
    56         if (cnt==0) return res;
    57         for (int i=0;i<n;i++) if (id[i]==-1) id[i]=cnt++;
    58         int all=0;
    59         for (int i=1;i<=tot;i++){
    60             int v=e[i].v,u=e[i].u;
    61             e[i].u=id[u];
    62             e[i].v=id[v];
    63             if (e[i].u!=e[i].v)
    64              e[i].w-=In[v],e[++all]=e[i];
    65         }
    66         tot=all;
    67         n=cnt;rt=id[rt];
    68     }
    69     return res;
    70 }
    71 int main(){
    72     while (scanf("%d%d%d%d",&n,&X,&Y,&Z)!=EOF&&n){
    73         if (!n&&!X&&!Y&&!Z) return 0;
    74         for (int i=1;i<=n;i++) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z);
    75         for (int i=1;i<=n;i++){
    76             int k,x;
    77             scanf("%d",&k);
    78             while (k--){
    79                 scanf("%d",&x);
    80                 if (x==i) continue;
    81                 insert(i,x,dis(p[i],p[x]));
    82             }
    83             insert(0,i,p[i].z*X);        
    84         }
    85         n++;
    86         int Ans=directedMST(0);
    87         printf("%d
    ",Ans);
    88     }
    89 }
  • 相关阅读:
    还原被删除的对象(域)
    Windows blue系列的安装
    转移active directry数据库文件
    使用指针让两个数交换
    针对被删除的AD DS对象执行授权还原
    这两天的总结
    小小问题
    程序2
    程序4
    程序1
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5535834.html
Copyright © 2011-2022 走看看