标签:
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