标签:
2 10 20 30 1 3 2 2 4 1 1 2 2 1 2 0 0 0 0
30HintIn 3‐dimensional space Manhattan distance of point A (x1, y1, z1) and B(x2, y2, z2) is |x2‐x1|+|y2‐y1|+|z2‐z1|.
最小树形图
题目描述的比较复杂,加重了构图的困难....因为确实不会做....
参照大神的构图方法,然后跑跑了一发模板(模板点这里),然后过了.....
/*
http://blog.csdn.net/liuke19950717
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1005;
struct node
{
int u,v;
int len;
}edge[maxn*maxn];
int pre[maxn],id[maxn],vis[maxn];
int in[maxn],tot;
int dir_mst(int root,int n,int m)
{
int ans=0;
while(1)
{
//先找出所有点的最小入边
/*memset(in,inf,sizeof(in)); //这样写会报错!*/
for(int i=0;i<n;++i)
{
in[i]=inf;
}
for(int i=0;i<m;++i)
{
int u=edge[i].u,v=edge[i].v;
if(edge[i].len<in[v]&&u!=v)
{
pre[v]=u;
in[v]=edge[i].len;
}
}
for(int i=0;i<n;++i)
{
if(i==root)
{
continue;
}
if(in[i]==inf)
{
return -1; //如果某点入度为零,必定找不到
}
}
//检查这些边是否构成了环
memset(id,-1,sizeof(id));
memset(vis,-1,sizeof(vis));
in[root]=0;
int cnt=0;
for(int i=0;i<n;++i)//标记环
{
ans+=in[i];
int v=i;
while(vis[v]!=i&&id[v]==-1&&v!=root)
{
vis[v]=i;
v=pre[v];
}
if(v!=root&&id[v]==-1)//缩点
{
for(int u=pre[v];u!=v;u=pre[u])
{
id[u]=cnt;
}
id[v]=cnt++;
}
}
if(cnt==0)
{
break;//无环
}
for(int i=0;i<n;++i)
{
if(id[i]==-1)
{
id[i]=cnt++;
}
}
//建立新图
for(int i=0;i<m;++i)
{
int u=edge[i].u,v=edge[i].v;
edge[i].u=id[u];
edge[i].v=id[v];
if(id[u]!=id[v])
{
edge[i].len-=in[v];
}
/*
edge[i].u=id[e[i].u];
edge[i].v=id[e[i].v];
if(edge[i].u!=edge[i].v)
{
edge[i].len-=in[v];
}*/
}
n=cnt;
root=id[root];
}
return ans;
}
int x[maxn],y[maxn],z[maxn];
int dis(int i,int j)//!!!!!!!!!啊啊啊啊啊
{
return abs(x[i]-x[j])+abs(y[i]-y[j])+abs(z[i]-z[j]);
}
int main()
{
int X,Y,Z,n;
while(scanf("%d%d%d%d",&n,&X,&Y,&Z),n|X|Y|Z)
{
tot=0;
for(int i=1;i<=n;++i)
{
scanf("%d%d%d",&x[i],&y[i],&z[i]);
node tp={0,i,z[i]*X};
edge[tot++]=tp;
}
for(int i=1;i<=n;++i)
{
int k;
scanf("%d",&k);
while(k--)
{
int t;
scanf("%d",&t);
if(i==t)
{
continue;
}
if(z[i]>=z[t])
{
int d=dis(i,t);
node tp={i,t,d*Y};
edge[tot++]=tp;
}
else
{
int d=dis(i,t);
node tp={i,t,d*Y+Z};
edge[tot++]=tp;
}
}
}
int root=0;
int ans=dir_mst(0,n+1,tot);
if(ans==-1)
{
printf("poor XiaoA\n");
}
else
{
printf("%d\n",ans);
}
}
return 0;
}
Hdu 4009 Transfer water【最小树形图】
标签:
原文地址:http://blog.csdn.net/liuke19950717/article/details/51346647