hdu 4009

来源:互联网 发布:paul smith 知乎 编辑:程序博客网 时间:2024/06/08 05:50

最小树形图模板

#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>#define N 1010#define M 1010000#define inf 100000000using namespace std;int a[N],b[N],c[N];int in[N],pre[N],id[N],vis[N];struct Edge{    int u,v,w;}edge[M];int cnt,n;inline int dis(int x,int y){    return abs(a[x]-a[y])+abs(b[x]-b[y])+abs(c[x]-c[y]);}int Directed_MST(int root){    int ret=0,i;    while(1){        for(i=0;i<=n;i++)in[i]=inf;        for(i=0;i<cnt;i++){            int u=edge[i].u,v=edge[i].v;            if(edge[i].w<in[v] && u!=v){                pre[v]=u;                in[v]=edge[i].w;            }        }        in[root]=0;        for(i=0;i<=n;i++)            if(in[i]==inf)return -1;        int node=0;        memset(id,-1,sizeof(id));        memset(vis,-1,sizeof(vis));        for(i=0;i<=n;i++){            ret+=in[i];            int v=i;            while(vis[v]!=i && 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]=node;                id[v]=node++;            }        }        if(node==0)break;        for(i=0;i<=n;i++)            if(id[i]==-1)                id[i]=node++;        for(i=0;i<cnt;i++){            int v=edge[i].v;            edge[i].u=id[edge[i].u];            edge[i].v=id[edge[i].v];            if(edge[i].u!=edge[i].v)                edge[i].w-=in[v];        }        n=node-1;        root=id[root];    }    return ret;}int main(){    int i,j,p,q;    int x,y,z;    while(scanf("%d %d %d %d",&n,&x,&y,&z)){        if(n==0 && x==0 && y==0 && z==0)break;        cnt=0;        for(i=1;i<=n;i++){            scanf("%d %d %d",&a[i],&b[i],&c[i]);            edge[cnt].u=0,edge[cnt].v=i,edge[cnt].w=c[i]*x;            cnt++;        }        for(i=1;i<=n;i++){            scanf("%d",&p);            for(j=1;j<=p;j++){                scanf("%d",&q);                if(q==i)continue;                if(c[q]<=c[i])                    edge[cnt].u=i,edge[cnt].v=q,edge[cnt].w=dis(i,q)*y;                else                    edge[cnt].u=i,edge[cnt].v=q,edge[cnt].w=dis(i,q)*y+z;                cnt++;            }        }        printf("%d\n",Directed_MST(0));    }}



原创粉丝点击