题目大意:有N个点,每个点都有相应的三维坐标(x,y,z)
现在要求每个点都能获得水,或者水的方式有两种
1.自己挖井,费用为X * 海拔高度z
2.铺设管道引水。
a.如果海拔高度小于引水处,费用为两地曼哈顿距离*Y
b.如果海拔高度大于饮水处,费用为两地曼哈顿距离*Y + Z
这代码还是挺好看的。。
https://vjudge.net/solution/3198132
就按照他的模板。
越看越像用 最大流的模板一样。。
https://vjudge.net/contest/179107#problem/A
int x[mxn],y[mxn],z[mxn];
int X,Y,Z;
int n,m;
int pre[mxn],id[mxn],vis[mxn],in[mxn];
struct edge{
int u,v,c;
void getE(int i,int j){
u=i,v=j;
c=abs(x[i]-x[j])+abs(y[i]-y[j])+abs(z[i]-z[j]);
c*=Y;
if(z[j]>z[i])
c+=Z;
}
}e[mxe];
int DMST(int s,int n){
int ret=0;
while(1){
mem(in,inf);
for(int i=1;i<=m;++i){
int u=e[i].u,v=e[i].v,c=e[i].c;
if(c<in[v]&u!=v){
pre[v]=u,in[v]=c;
}
}
for(int i=1;i<=n;++i)
if(in[i]==inf&&i!=s)
return -1;
in[s]=0;
int cnt=0;
mem(id,-1);
mem(vis,-1);
for(int i=1;i<=n;++i){
ret+=in[i];
int v=i;
while(vis[v]!=i&&id[v]==-1&&v!=s)
vis[v]=i,v=pre[v];
if(id[v]==-1&&v!=s){//处理环的地方
id[v]=++cnt;
for(int u=pre[v];u!=v;u=pre[u])
id[u]=cnt;
}
}
if(cnt==0)break;//没有环就退出
for(int i=1;i<=n;++i)if(id[i]==-1)id[i]=++cnt;
for(int i=1;i<=m;++i){
int u=e[i].u,v=e[i].v;
e[i].u=id[u],e[i].v=id[v];
if(id[u]!=id[v])
e[i].c-=in[v];
}
n=cnt;
s=id[s];
}
return ret;
}
int main(){
//freopen("in.txt","r",stdin);
while(~sf("%d%d%d%d",&n,&X,&Y,&Z)&&n){
rep(i,1,n)sf("%d%d%d",&x[i],&y[i],&z[i]);
m=0;
for(int i=1;i<=n;++i){
int k;
sf("%d",&k);
while(k--){
int v;sf("%d",&v);
if(v==i)continue;
e[++m].getE(i,v);
}
}
for(int i=1;i<=n;++i){
++m;
e[m].u=n+1,e[m].v=i;
e[m].c=abs(z[i])*X;
}
int ans=DMST(n+1,n+1);
if(ans==-1)
puts("poor XiaoA");
else pf("%d\n",ans);
}
}
本文探讨了一个关于N个三维坐标点的供水问题,提出了两种供水方式:自行挖井和铺设管道引水,并详细介绍了使用最大流算法解决该问题的具体实现过程。
398

被折叠的 条评论
为什么被折叠?



