每一户人家水的来源有两种打井和从别家接水,每户人家都可能向外输送水。

  打井和接水两种的付出代价都接边。设一个超级源点,每家每户打井的代价就是从该点(0)到该户人家(1~n)的边的权值。接水有两种可能,从高处接水,那么代价是哈密顿距离与Y的乘积(可以认为就是水管的费用);从低处接水,还要加上付出水泵的钱(水管+水泵的费用)。这样就可以建图了。图论,会建图的话问题就解决一半了。

  然后,用模版来解题。不过朱刘算法的模版时间复杂度的差异还是蛮大的。我的模版的建图是邻接矩阵,时间复杂度是O(N^3)。超时,过不了。在网上找了一份按前向星(边的起点、终点、权值)建图的模版。AC了。该算法的复杂度是O(M)。

 #include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = , M=,INF=0x3f3f3f3f;
int pre[N],id[N],in[N],vis[N];
int tot;//边数
struct node
{
int u,v,w;
}e[M];
void adde(int i,int j,int k)
{
e[tot].u=i;e[tot].v=j;e[tot++].w=k;
}
int zhuliu(int root ,int vn)
{
int ans=;
int cnt;
while()
{
for(int i=;i<vn;i++)
in[i]=INF,id[i]=-,vis[i]=-;
for(int i=;i<tot;i++)
{
if(in[e[i].v]>e[i].w && e[i].u!=e[i].v)
{
pre[e[i].v]=e[i].u;
in[e[i].v]=e[i].w;
}
}
in[root]=;
pre[root]=root;
for(int i=;i<vn;i++)
{
ans+=in[i];
if(in[i]==INF)//这一步可以看出是否存在这样一棵树形图,因此可以略去DFS
return -;
}
cnt=;
for(int i=;i<vn;i++)
{
if(vis[i]==-)
{
int t=i;
while(vis[t]==-)
{
vis[t]=i;
t=pre[t];
}
if(vis[t]!=i || t==root) continue;
for(int j=pre[t];j!=t;j=pre[j])
id[j]=cnt;
id[t]=cnt++;
}
}
if(cnt==) break;
for(int i=;i<vn;i++)
if(id[i]==-)
id[i]=cnt++;
for(int i=;i<tot;i++)
{
int u,v;
u=e[i].u;
v=e[i].v;
e[i].u=id[u];
e[i].v=id[v];
e[i].w-=in[v];
}
vn=cnt;
root=id[root];
}
return ans;
} struct Node
{
int a,b,c;
}nd[N];
int main()
{
//freopen("test.txt","r",stdin);
int n,x,y,z,i,j,k,d;
while(scanf("%d%d%d%d",&n,&x,&y,&z)!=EOF)
{
if(!n) break;
tot=;
for(i=;i<=n;i++)
{
scanf("%d%d%d",&nd[i].a,&nd[i].b,&nd[i].c);
adde(,i,nd[i].c*x);
}
for(i=;i<=n;i++)
{
scanf("%d",&k);
while(k--)
{
scanf("%d",&j);
if(i==j) continue;
d=abs(nd[i].a-nd[j].a)+abs(nd[i].b-nd[j].b)+abs(nd[i].c-nd[j].c);
d*=y;
if(nd[i].c<nd[j].c) d+=z;
adde(i,j,d);
}
}
int ans=zhuliu(,n+);
if(ans==-) printf("poor XiaoA\n");
else printf("%d\n",ans);
}
return ;
}

下面是邻接矩阵建图的模版,虽然超时了。但是模版还是有借鉴意义的。模版来自哈工大出版的《图论及应用》。

 #include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = , INF=0x3f3f3f3f;
int Map[N][N];
bool vis[N],f[N];
//f是缩点标记,1表示该点已经被缩掉
int pre[N];
int zhuliu(int n)
{
int sum=;
int i,j,k;
for(i=;i<n;i++)
{
f[i]=;
Map[i][i]=INF;
}
pre[]=;
while()
{
//求最短弧集合E0
for(i=;i<n;i++)
{
if(f[i]) continue;
pre[i]=i;
for(j=;j<n;j++)
if(!f[j]&&Map[j][i]<Map[pre[i]][i]) pre[i]=j;
if(pre[i]==i) return -; //没有入边,不存在最小树形图
}
//检查E0
for(i=;i<n;i++)
{
if(f[i]) continue ;
//从当前点开始找环
for(j=;j<n;j++) vis[j]=;
vis[]=;
j=i;
do
{
vis[j]=;
j=pre[j];
}
while(!vis[j]) ;
if(!j) continue; //没有找到环
//收缩G中的有向环
i=j;
//将整个环的权值保存,累计入原图的最小树形图
do
{
sum+=Map[pre[j]][j];
j=pre[j];
}
while(j!=i) ;
j=i;
//对与环上的点有关的边,修改边权
do
{
for(k=; k<n; k++)
if(!f[k]&&Map[k][j]<INF&&k!=pre[j])
Map[k][j]-= Map[pre[j]][j];
j=pre[j];
}
while(j!=i) ;
//缩点,将整个环缩成i号点,所有与环上的点有关的边转移到点i
for(j=;j<n;j++)
{
if(j==i) continue;
for(k=pre[i]; k!=i; k=pre[k])
{
if(Map[k][j]<Map[i][j]) Map[i][j] =Map[k][j];
if(Map[j][k]<Map[j][i]) Map[j][i] =Map[j][k];
}
}
//标记环上其他的点为被缩掉
for(j=pre[i];j!=i;j=pre[j]) f[j] =;
//当前环缩点结束,形成新的图G’,跳出继续求G’的最小树形图
break;
}
//如果所有的点都被检查且没有环存在,现在的最短弧集合E0就是
//最小树形图,累计如sum, 算法结束
if(i==n)
{
for(i=;i<n;i++) if(!f[i]) sum+=Map[pre[i]][i];
break;
}
}
return sum;
} struct node
{
int a,b,c;
}nd[N];
int main()
{
//freopen("test.txt","r",stdin);
int n,x,y,z,i,j,k,d;
while(scanf("%d%d%d%d",&n,&x,&y,&z)!=EOF)
{
if(!n) break;
for(i=;i<=n;i++)
for(j=;j<i;j++)
Map[j][i]=Map[i][j]=INF;
for(i=;i<=n;i++)
{
scanf("%d%d%d",&nd[i].a,&nd[i].b,&nd[i].c);
Map[][i]=nd[i].c*x;
}
for(i=;i<=n;i++)
{
scanf("%d",&k);
while(k--)
{
scanf("%d",&j);
if(i==j) continue;
d=abs(nd[i].a-nd[j].a)+abs(nd[i].b-nd[j].b)+abs(nd[i].c-nd[j].c);
d*=y;
if(nd[i].c>=nd[j].c) d+=z;
Map[i][j]=min(d,Map[i][j]);
}
}
printf("%d\n",zhuliu(n+));
}
return ;
}

hdu4009 Transfer water 最小树形图的更多相关文章

  1. HDU4009 Transfer water —— 最小树形图 + 不定根 + 超级点

    题目链接:https://vjudge.net/problem/HDU-4009 Transfer water Time Limit: 5000/3000 MS (Java/Others)    Me ...

  2. HDU 4009 Transfer water 最小树形图

    分析:建一个远点,往每个点连建井的价值(单向边),其它输水线按照题意建单向边 然后以源点为根的权值最小的有向树就是答案,套最小树形图模板 #include <iostream> #incl ...

  3. HDOJ 4009 Transfer water 最小树形图

    Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) T ...

  4. HDU4009 Transfer water 【最小树形图】

    Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) T ...

  5. POJ 3164 Command Network 最小树形图模板

    最小树形图求的是有向图的最小生成树,跟无向图求最小生成树有很大的区别. 步骤大致如下: 1.求除了根节点以外每个节点的最小入边,记录前驱 2.判断除了根节点,是否每个节点都有入边,如果存在没有入边的点 ...

  6. HDU 4009——Transfer water——————【最小树形图、不定根】

    Transfer water Time Limit:3000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64u Subm ...

  7. HDU 4009 Transfer water(最小树形图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4009 题意:给出一个村庄(x,y,z).每个村庄可以挖井或者修建水渠从其他村庄得到水.挖井有一个代价, ...

  8. 最小树形图(hdu4009)

    Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) T ...

  9. HDU4009:Transfer water(有向图的最小生成树)

    Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)To ...

随机推荐

  1. BZOJ 1106: [POI2007]立方体大作战tet 树状数组 + 贪心

    Description 一个叫做立方体大作战的游戏风靡整个Byteotia.这个游戏的规则是相当复杂的,所以我们只介绍他的简单规 则:给定玩家一个有2n个元素的栈,元素一个叠一个地放置.这些元素拥有n ...

  2. Sql Server 查询性能查看

    dbcc dropcleanbuffers --清除buffer pool里的数据页面 dbcc freeproccache --清除memtoleave和buffer pool里的执行计划内存 se ...

  3. jupyter记事本的安装和简单应用

    1.概述 jupyter记事本是一个基于Web的前端,被分成单个的代码块或单元.根据需要,单元可以单独运行,也可以一次全部运行.这使得我们可以运行某个场景,看到输出结果,然后回到代码,根据输出结果对代 ...

  4. Git 基础教程 之 添加远程仓库

    b, 本地内容推送至远程库上         git push -u origin master        实际上是把当前分支master推送到远程仓库,第一次推送时,加上-u参数, 表示Git不 ...

  5. BZOJ 1179 抢掠计划atm (缩点+有向无环图DP)

    手动博客搬家: 本文发表于20170716 10:58:18, 原地址https://blog.csdn.net/suncongbo/article/details/81061601 https:// ...

  6. 编写App测试用例的关注点

    如何做到测试用例的百分百覆盖一直是测试用例编写过程中的难点,首先在测试时我们经常会遇见一些常见的bug,那么我们可以在编写测试用例时考虑到这些点.    一:关于业务逻辑               ...

  7. (25)Spring Boot使用自定义的properties【从零开始学Spring Boot】

    spring boot使用application.properties默认了很多配置.但需要自己添加一些配置的时候,我们应该怎么做呢. 若继续在application.properties中添加 如: ...

  8. 一文快速上手Logstash

    原文地址:https://cloud.tencent.com/developer/article/1353068 Elasticsearch是当前主流的分布式大数据存储和搜索引擎,可以为用户提供强大的 ...

  9. nginx中父子进程工作的主体函数

    依据Nginx(0.7.67版本号)的代码.对Nginx主要的进程创建,进程主体以及事件处理进行了简要的分析. 基本上,父进程(即主进程)一開始会初始化及读取配置.并载入各模块的功能,然后fork() ...

  10. Ext.TabPanel中的items具体解释

    Ext.TabPanel中的items: (来自项目源代码中的items条目代码) items:{ id:"opt1", title:"默认页面", tabTi ...