[kuangbin带你飞]专题八 生成树 H

来源:互联网 发布:在线直播电视软件 编辑:程序博客网 时间:2024/05/21 10:42

题目地址:https://vjudge.net/contest/67265#problem/H
AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 1000+10;const int MAXM = MAXN*MAXN;struct Edge{    int u,v,cost;};struct Point{    int x,y,z;};Point p[MAXN];Edge edge[MAXM];int pre[MAXN],id[MAXN],visit[MAXN],in[MAXN];int x,y,z;int getCost(int u,int v){    int ans=0;    int dis=abs(p[u].x-p[v].x)+abs(p[u].y-p[v].y)+abs(p[u].z-p[v].z);    ans+=y*dis;    if(p[u].z<p[v].z)        ans+=z;    return ans;}int zhuliu(int root,int n,int m,Edge edge[]){    int res=0,u,v;    while(1){        for(int i=0;i<n;i++)            in[i]=INF;        for(int i=0;i<m;i++)        if(edge[i].u!=edge[i].v && edge[i].cost<in[edge[i].v]){            pre[edge[i].v]=edge[i].u;            in[edge[i].v]=edge[i].cost;        }        for(int i=0;i<n;i++)            if(i!=root && in[i]==INF)            return -1;        int tn=0;        memset(id,-1,sizeof(id));        memset(visit,-1,sizeof(visit));        in[root]=0;        for(int i=0;i<n;i++){            res+=in[i];            v=i;            while(visit[v]!=i && id[v]==-1 && v!=root){                visit[v]=i;                v=pre[v];            }            if(v!=root && id[v]==-1){                for(int u=pre[v];u!=v;u=pre[u])                    id[u]=tn;                id[v]=tn++;            }        }        if(tn==0) break;        for(int i=0;i<n;i++)            if(id[i]==-1)            id[i]=tn++;        for(int i=0;i<m;i++){            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].cost-=in[v];        }        n=tn;        root=id[root];    }    return res;}int main(){    int n;    while(~scanf("%d%d%d%d",&n,&x,&y,&z) && n){        for(int i=0;i<n;i++)        scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z);        int u,v,cost;        int L=0;        for(int i=0;i<n;i++){            int k;            scanf("%d",&k);            u=i;            while(k--){            scanf("%d",&v);            v--;            if(u==v) continue;            cost=getCost(u,v);             edge[L].u=u;                edge[L].v=v;                edge[L++].cost=cost;            }            edge[L].u=n;            edge[L].v=i;            edge[L++].cost=x*p[i].z;        }        int ans=zhuliu(n,n+1,L,edge);        printf("%d\n",ans);    }}
0 0