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

  打井和接水两种的付出代价都接边。设一个超级源点,每家每户打井的代价就是从该点(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. 重置root管理员密码(RedHat、CentOS、Fedora)

    重启Linux系统主机并出现引导画面时,按下键盘上的e键进入内核编辑界面. 在Linux16参数这行后面追加"rd.break"参数,然后按下Ctrl+x组合键来运行修改后的内核程 ...

  2. 26.bulk批量操作

    主要知识点 1.bulk语法 2.bulk使用时的注意事项 3.bulk size 对es性能的影响     一.bulk语法 每一个操作要两个json串(delete操作除外),每个json串占一行 ...

  3. Python之Django的Model2

    一.创建数据库 创建数据库 进入数据库: mysql -uroot -p 创建数据库: CREATE DATABASE test1 CHARSET=utf8; 连接数据库 虚拟环境中安装数据库模块:p ...

  4. "AssertionError: View function mapping is overwriting an existing endpoint function"如何解决

    使用Flask定义URL的时候,如果出现"AssertionError: View function mapping is overwriting an existing endpoint ...

  5. Spring事务的传播行为分析

    前言 最近项目有涉及到Spring事务,所以工作之余,想认真了解学习下Spring事务,查阅了若干资料,做了一个demo(PS:参考了大牛的). 现分享总结如下: 1.Spring 事务的简介 理解事 ...

  6. 洛谷 P2728 纺车的轮子 Spinning Wheels

    P2728 纺车的轮子 Spinning Wheels 题目背景 一架纺车有五个纺轮(也就是五个同心圆),这五个不透明的轮子边缘上都有一些缺口.这些缺口必须被迅速而准确地排列好.每个轮子都有一个起始标 ...

  7. cogs 9. 中心台站建设。。。

    9. 中心台站建设 ★★☆   输入文件:zpj.in   输出文件:zpj.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述]     n个城市之间有通讯网络,从这n个城 ...

  8. RecyclerView的使用(1)之HelloWorld

    原创文章.转载请注明 http://blog.csdn.net/leejizhou/article/details/50670657 RecyclerView是伴随Android 5.0公布的新控件, ...

  9. C++静态变量本身可否是一个实例对象

    一般书上总是用int来举例,那个太简单.如果静态变量本身可否是一个实例对象呢?应该是可以,但是这样涉及到它的构造函数以及它内部的静态变量如何初始化两个问题,换而言之,这个静态变量本身应该如何初始化?这 ...

  10. iOS- &quot;unacceptable content-type: text/plain&quot;等content-type bug解决方式

    常常在使用AFN的时候会出现content-type错误,缺少请求类型,比方"unacceptable content-type: text/plain" 解决方法: 1.在网络请 ...